题解 P2655 【2038年问题】
发现c++党都是先确定年份,再确定月份及以下时间,感到震惊
其实可以直接从秒开始往年推,先把秒加上最大限度的时间,再把秒化为分,以此类推
核心
计算天数时需考虑到月份和年份(每月天数不同,闰年和平年不同),所以需一次次推,天数减去当月的天数后,将月份加1,如果月份大于12,年份加1
#include <iostream>
using namespace std;
long long t,y,m,d,h,mi,s,len;//变量依次代表数据组数,年,月,天,小时,分钟,秒,时间的变量长度
long long n[33];
int mo[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
void check(){//判断闰年,并修改2月天数
if((y%4==0&&y%100!=0)||y%400==0)
mo[2]=29;
else
mo[2]=28;
}
int main(){
int i,j;
long long k;
n[1]=1;//记忆化搜索,直接调用相应长度的二进制数的值
for(i=2;i<=32;i++)
n[i]=n[i-1]*2;
cin>>t;
while(t--){
cin>>len>>y>>m>>d>>h>>mi>>s;
s+=n[len]-1;//注意这里需要减1,因为不能计时到最大长度
k=s/60;//化成分钟数
s%=60;//化简后的秒数
mi+=k;
k=mi/60;//化成小时
mi%=60;//化简后的分钟
h+=k;
k=h/24;
h%=24;
d+=k;
if(m==2)//前方高能,先判断闰年
check();
while(d>mo[m]){
d-=mo[m];//减去当月的天数
m++;//月份+1
if(m>12){//年份+1
m=1;
y++;
}
if(m==2)//月份为2时,要检查闰年和平年
check();
}
cout<<y<<" "<<m<<" "<<d<<" "<<h<<" "<<mi<<" "<<s<<endl;//输出
}
return 0;//功德圆满
}