算法提高 日期计算
问题描述
已知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
#include<stdio.h>
/*判断闰年的函数*/
int is_rn(int i)
{
if((i%4==0&&i%100!=0)||i%400==0)
return 1;
return 0;
}
/*思路是先计算出距离2011 11 11 相差几天,多为正,少为负,赋值给变量s
在计算距离天数的过程中,日月部分相当于将最开始输入的年份日期“位移”到最开始输入的年份的11 月 11 日。
所以——所以——所以,very important
涉及闰年判断的2月,使用的是当前年来判断是否为闰年
而在位移之后的年部分,因为已经是本年的11 月 11 日了
如果最开始输入的年份是在2011年之前,所需加上的天数涉及到的闰年部分使用的是当前年的下一年来判断闰年,例如2008 11 11 ,
你要位移到2009 11 11 经过的2月肯定是2009年的2月
若是在之后,则使用当前年来判断闰年(int i=当前年,for(i=2012;i<=最开始输入的年份;i++)
(在2011之前,相当于向2011前进;在2011之后,相当于让2011前进)。
*/
int main()
{
int y,m,d;
int s=0;
int i;
scanf("%d%d%d",&y,&m,&d);
/*下一行是经过优化的部分*/
s+=(d-11);
/*月部分 11月就不用再判断了,为0*/
if(m==12) s+=30;
for(i=m;i<11;i++)
{
switch(i)
{
case 1:case 3:case 5:case 7:case 8:case 10:s-=31;break;
case 2:
if(is_rn(y))
{
s-=29;
}
else
{
s-=28;
}
break;
case 4:case 6:case 9:s-=30;
}
}
/*年部分*/
if(y>2011)
{
for(i=2012;i<=y;i++)
{
if(is_rn(i))
{
s+=366;
}
else
{
s+=365;
}
}
}
if(y<2011)
{
for(i=y;i<2011;i++)
{
if(is_rn(i+1))
{
s-=366;
}
else
{
s-=365;
}
}
}
/*计算星期几的部分*/
int mode;
mode=s%7;
if(mode<=0)
{
if(5+mode>0) printf("%d",5+mode);
else printf("%d",7+(5+mode));
}
else
{
if(mode+5==7) printf("7");
else
printf("%d",(5+mode)%7);
}
return 0;
}