星期几的问题

2019-04-14 20:39发布

已知公元1年1月1日是星期一,问某年某月某日是星期几? Input
输入为三个正整数y,m,d,分别代表年、月、日。其中,1≤y≤500000000000, m和d保证合法。 Output
输出星期几,星期一到星期六分别用1到6表示,星期天用7表示。 首先需要明确的一点是,万年历以400年为一个周期!!也就是说在进行进一步的运算之前,可以先让year对400取模,从而大大简化计算。 下面先分析一下我的思路:不可能把每一年的总天数加起来再对7求模,这样运算量太大了。因为一个平年对7取模是1,一个闰年对七取模是2,所以可以一步步的缩小规模,将一个比400小的年数通过counter记录增加的余数,逐步减小到公元1年,然后再求出总天数,这样就好算很多了。 因为这个算法是我当时粗略的想的,感觉大致是对的,但是真正实现起来的时候出现了几个小问题,下面会具体分析一下。 #include int get_weekday(long long year,int month,int day); int get_counter(long long year,int month,int day); int get_days(int month,int day); int is_leap(long long year); int main() { long long year; int month,day; int result; scanf("%lld%d%d",&year,&month,&day); result=get_weekday(year,month,day); printf("%d ",result); return 0; } int get_weekday(long long year,int month,int day) { int counter=0,days=0; int result; counter=get_counter(year,month,day); days=get_days(month,day); result=(counter+days)%7; if(!result) { return 7; } return result; } int get_counter(long long year,int month,int day) { int counter=0; year%=400; if(is_leap(year)) { if(month<=2) { counter--; } } if(!year) { counter--; } for(;year>1;year--) { if(is_leap(year)) { counter+=2; } else { counter++; } } return counter%7; } int is_leap(long long year) { int condition1,condition2; condition1=!(year%4)&&(year%100); condition2=!(year%400); if(condition1||condition2) { return 1; } return 0; } int get_days(int month,int day) { int monthdays[12]={0,31,28,31,30,31,30,31,31,30,31,30}; int days=0; int i=0; for(i=0;i
  1. year的数据类型不能是int,设为long long就够了,否则会出现溢出;
  2. 第一次进行year对400的取模时,考虑会有的年份是400的倍数,取模后会变成公元0年,但实际我们后来计算天数的时候都是按照公元1年1月1日是星期一来进行计算的,我们又知道每往前推一年天数会少一天,所以counter需要自减一;
  3. 还有一种情况,比如要求1960 2 25是星期几,如果直接将1960%400=360判断为闰年,会让counter增加两天,但是实际上在2.29号之前的天数不会受该年是否为闰年的影响,只有在二月份之后的天数会受影响,因此在进入循环语句之前,先判断月份是否比二大,再继续操作;
  4. 最后一件小事情就是monthdays中的数组天数总是上一个月的天数,因此第一个元素是0,第十二个元素是第十一月的天数30。
以上均是个人所想,如果有不足或者更简单的做法请一定要在评论里指出哦!