问题描述
已知2011年11月11日是星期五,问YYYY年MM月DD日是星期几?注意考虑闰年的情况。尤其是逢百年不闰,逢400年闰的情况。
输入格式
输入只有一行
YYYY MM DD
输出格式
输出只有一行
W
数据规模和约定
1599 <= YYYY <= 2999
1 <= MM <= 12
1 <= DD <= 31,且确保测试样例中YYYY年MM月DD日是一个合理日期
1 <= W <= 7,分别代表周一到周日
样例输入
2011 11 11
样例输出
5
思路:对照法。
首先规定一个已经确定过星期几的日期,这里以2017(平年)年1月1日星期7,为标准。
输入的年份分为两种情况:
第一种:
大于规定的年份,则要计算出,规定年份到输入的年份间的所有天数之和,再模上7(规定的是星期7)得到的即是结果
第二种:
小于或等于规定年份,计算该年份到规定年份前的所有天数,再计算在输入的年里,month和day共用多少天,用总天数 - 该年的里实际天数,用7模上这个结果
#include<stdio.h>
int isLeapYear(int n) { //判断是否是润年
if (n%4==0 && n%100!=0 || n%400==0)
return 1;
return 0;
}
int md[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31};//全局变量定义,统一定义平年每月月份
int main() {
int year,month,day;
int i,sum=0,td=0;
while (scanf("%d%d%d",&year,&month,&day)!=EOF) {
sum=0;
td=0;
if (year>=2017) { //输入的年份>=2017年时
for (i=2017; i<year; i++) {
sum+=365; //计算2017到year年前的所有天数
if (isLeapYear(i)) //是闰年天数加1
sum+=1;
}
for (i=1; i<month; i++) {
sum+=md[i]; //计算在输入的这年里,所有月份的天数之和
if (i==2&&isLeapYear(year)) //判断这年是不是闰年,是则2月份是的天数要加一
sum+=1;
}
sum+=day-1; //最终准确的天数
printf("%d\n",sum%7==0? 7:sum%7);
}else if (year<2017) { //输入的年份小于2017
for (i=year; i<2017; i++) { //计算输入的年份到规定的2017年前的总天数
sum+=365;
if (isLeapYear(i))//是闰年加1天
sum+=1;
}
for (i=1; i<month; i++) {
td+=md[i]; //td为输入年份该年里的所有天数
if (i==2&&isLeapYear(year)) { //如果是二月,且该年是闰年的话。
td+=1; //增加1天
}
}
td+=day-1;
sum-=td;
printf("%d\n",7-sum%7);
}
}
return 0;
}
分析:
sum+=day-1; //最终准确的天数
这里是将大于2017年所有的天数进行一次矫正。2017.1.1是星期7,后面每一个7的倍数取%7等于0,而1%7=1的,所以-1矫正即可。
td+=day-1;
sum-=td;
同样,如果输入的年份小于参照的年份,先进行td+=day-1;将其相对2017.1.1矫正。大哥比方,2016.12.31是星期6,sum-=td;通过矫正后,sum=1,所以输出结果通过7-sum%7再次矫正。