YYYY MM DD
W
1 <= MM <= 12
1 <= DD <= 31,且确保测试样例中YYYY年MM月DD日是一个合理日期
1 <= W <= 7,分别代表周一到周日
我一直对这种日期计算计算的题目存在恐惧感,因为这类题目普遍不难,但是多一天少一天的问题搞得我头都大了,好在今天仔细在纸上画了一下,想出了一种比较通用的做法,如有雷同,纯属你抄我开玩笑,但我还是要好好整理一下解题思路
1.闰年问题:当然是通过函数判断闰年,我想如果不是万年一见的水题,一般计算日期时间都是要考虑闰年的。闰年的两种情况:1.能被4整除但不能被100整除;2.能被400整除,也就是常说的四年一闰,百年不闰,四百年再闰
2.天数问题:这里题目一般都会给出一个基础日期的信息,但是相信我,最好是花点时间算出某一年1月1号的信息,因为这会让思路变得很清晰,如果你算不出来,也有一个投机取巧的方法(假如条件允许),电脑下面的时间可以给你提供很全面正确的信息,有了基础天数后,以本题为例,2011年1月1日是星期6。
首先算年份差所带来的天数差
(1)给出的年份比基础年份小或者就是2011年,比如2009年,我们首先计算2009年1月1日到2011年1月1日的天数,相信这个应该难不倒你吧,闰年366天,非闰年365天,2009年开始,算完2010年结束。
(2)给出的年份比基础年份大,比如2013年,当然就是从2011年开始,算完2012年结束
经过这个步骤,得到day1
然后算由于月份和天的差所带来的天数差
(1)首先当然是计算1月1日到给定的日期(比如3月8号)的天数,计算的时候是用循环,从1月开始加,加完2月结束,最后再加上8天,但是注意,你此时算出的天数多了1,举个例子,1月1日到1月3日有几天?当然是2天,这要比3多1天,因为起始点就是1了,明白了这个,我们就可以用得出的天数减1,从而获得了第二个天数day2
关键时刻,计算真实的天数差
(1)如果给出的年份小于等于基础年份,那么我们得到的day1实际上是算多了,而且正好多出了day2天,所以真正的天数差是day1-day2
(2)如果给出的年份大于基础年份,那么天数实际上是算少了,少了day2天,所以真正的天数是day1+day2
在得出天数之后,我们还要分情况,首先将得到的天数差day%7,得到星期差
(1)如果给出的年份小于等于基础年份,那么应该从基础时间(星期六)向负方向数day%7天,注意1之后要变成7
(2)如果给出的年份大于基础年份,那么应该从基础时间(星期六)向正方向数day%7天,注意7之后要变成1
最终我们就得到了正确的星期
#include<iostream>
#include<cmath>
using namespace std;
bool leap(int year)
{
if(year%4==0&&year%100!=0)
return true;
if(year%400==0)
return true;
return false;
}
int getYD(int year)
{
int sum=0;
int i;
if(year<=2011)
{
for(i=year;i<2011;i++)
{
if(leap(i))
sum+=366;
else
sum+=365;
}
}
if(year>2011)
{
for(i=2011;i<year;i++)
{
if(leap(i))
sum+=366;
else
sum+=365;
}
}
return sum;
}
int getMD(int year,int mon,int day)
{
int i;
int sum=0;
for(i=1;i<mon;i++)
{
if(i==1||i==3||i==5||i==7||i==8||i==10||i==12)
sum+=31;
if(i==4||i==6||i==9||i==11)
sum+=30;
if(i==2&&leap(year))
sum+=29;
if(i==2&&!leap(year))
sum+=28;
}
sum=sum+day-1;
return sum;
}
int main()
{
int year,mon,day,sum;
while(cin>>year>>mon>>day)
{
sum=getYD(year);
//cout<<getMD(year,mon,day)<<endl;;
if(year<2011)
{
sum=sum-getMD(year,mon,day);
//cout<<sum<<endl;
cout<<(sum%7==6?7:abs(6-(sum%7)))<<endl;
}
else
{
sum=sum+getMD(year,mon,day);
//cout<<sum<<endl;
cout<<((6+(sum%7))>7?((6+(sum%7))%7):(6+(sum%7)))<<endl;
}
}
return 0;
}