我一直对这种日期计算计算的题目存在恐惧感,因为这类题目普遍不难,但是多一天少一天的问题搞得我头都大了,好在今天仔细在纸上画了一下,想出了一种比较通用的做法,如有雷同,纯属你抄我开玩笑,但我还是要好好整理一下解题思路
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; }