【题目链接】
【题目考点】
1… 取模运算
【解题思路】
我们用的是现实日历,题目中设定的是特殊日历,两种历法的一天是一样长的。也就是说两种历法的秒的长度是不一样的。
先输入现实日历的日期。
1. 求时分秒
求出从当天0时0分0秒到当前时间h时m分s秒的总秒数ts,为ts=h*3600+m*60+s
现实日历中一天为
24
∗
60
∗
60
=
86400
24*60*60=86400
24∗60∗60=86400秒,特殊日历中一天为
10
∗
100
∗
100
=
100000
10*100*100=100000
10∗100∗100=100000秒。
将现实日历的秒数转为特殊日历中的秒数,需要做
t
s
/
86400
∗
100000
=
t
s
∗
125
/
108
ts/86400*100000=ts*125/108
ts/86400∗100000=ts∗125/108,即ts = ts*125/108
而后在特殊日历中:
ts%100
为秒数,ts/100%100
为分钟数,ts/10000
为小时数。
2. 求日月年
把2000年1月1日当做第0天,求出该日期是第几天。
设一个函数getDayNum获取y年m月d日是从2000年1月1日起的第几天。
- i从2000遍历到y-1,根据第i年是否是闰年统计每年的天数,加和。
- i从1遍历到m-1,统计第i月的天数,加和。
- 最后天数加上d-1(由于日期从1开始)
用getDayNum函数求出总天数td,而后将该天数转为特殊日历中的日、月、年。
特殊日历中10天一周,10周一个月,也就是100天一个月。10个月1年。由于日、月从1开始,所以求出的数值要加1。
td%100+1
即为日,td/100%10+1
即为月,td/1000
为年。
【题解代码】
解法1:
#include<bits/stdc++.h>
using namespace std;
bool isLeap(int y)//y是否是闰年
{
return y%400 == 0 || y%100 != 0 && y%4 == 0;
}
int getDayNum(int y, int m, int d)
{
int day = 0;//从2000.1.1到y年m月d日的总天数
for(int i = 2000; i < y; ++i)
{
if(isLeap(i))
day += 366;
else
day += 365;
}
for(int i = 1; i < m; ++i)
{
if(i == 2)
day += isLeap(y) ? 29 : 28;
else if(i == 4 || i == 6 || i == 9 || i == 11)
day += 30;
else
day += 31;
}
day += d-1;
return day;
}
int main()
{
int n, k, h, mi, s, d, mo, y, td, ts;
scanf("%d", &n);
while(n--)
{
scanf("%d:%d:%d %d.%d.%d", &h, &mi, &s, &d, &mo, &y);//h:时 mi:分 s:秒 d:日 mo:月 y:年
ts = h*3600+mi*60+s;//从0:0:0到h:mi:s的总秒数
ts = ts*125/108;//将现实日历中的秒数转为特殊日历中的秒数。
s = ts%100, ts /= 100;//特殊日历下的秒、分、时
mi = ts%100, ts /= 100;
h = ts;
td = getDayNum(y, mo, d);//从1.1.2000到d.mo.y的总天数
d = td%100+1, td /= 100;//特殊日历下的日、月、年
mo = td%10+1, td /= 10;//日、月从1开始,所以要加1
y = td;
printf("%d:%d:%d %d.%d.%d\n", h, mi, s, d, mo, y);//注意:月日从1开始
}
return 0;
}
解法2:
#include<bits/stdc++.h>
using namespace std;
bool isLeap(int y)//y是否是闰年
{
return y%400 == 0 || y%100 != 0 && y%4 == 0;
}
int getDayNum(int y, int m, int d)
{
int day = 0;//从2000.1.1到y年m月d日的总天数
for(int i = 2000; i < y; ++i)
{
if(isLeap(i))
day += 366;
else
day += 365;
}
for(int i = 1; i < m; ++i)
{
if(i == 2)
day += isLeap(y) ? 29 : 28;
else if(i == 4 || i == 6 || i == 9 || i == 11)
day += 30;
else
day += 31;
}
day += d-1;
return day;
}
int main()
{
int n, k, h, mi, s, d, mo, y, td, ts;
scanf("%d", &n);
while(n--)
{
scanf("%d:%d:%d %d.%d.%d", &h, &mi, &s, &d, &mo, &y);//h:时 mi:分 s:秒 d:日 mo:月 y:年
ts = h*3600+mi*60+s;//从0:0:0到h:mi:s的总秒数
ts = ts*125/108;//将现实日历中的秒数转为特殊日历中的秒数。
s = ts%100;//特殊日历下的秒、分、时
mi = ts/100%100;
h = ts/10000;
td = getDayNum(y, mo, d);//从1.1.2000到d.mo.y的总天数
d = td%100+1;//特殊日历下的日、月、年
mo = td/100%10+1;//日、月从1开始,所以要加1
y = td/1000;
printf("%d:%d:%d %d.%d.%d\n", h, mi, s, d, mo, y);//注意:月日从1开始
}
return 0;
}