题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1308
求日期的题目,没什么难度,但是特别需要注意细节。
在Discuss中有讨论,提到了关于日期的计算:
1/1/1是星期日
1582年之前,只要能被4整除就是闰年
1582之后,就是按照现在的规则是闰年
1582年10月4日之后就是1582年10月15日,5号到14号是没有的
去掉这些天时为了补偿回之前错误的闰年规则所多算的天数
1752年9月2号之后就是1752年9月14号,3号到13号是没有的
当然这些都属于历史原因了,一步一步可以计算模拟,但是需要考虑太多的东西,之前做这些题目都是一个一个算,后来发现有公式可以计算:
计算出当前日期到公元1年1月1日的总天数,而那一天刚好是周一(网上也有说是周日的,但是根据周一可以AC)
int GetWeek(int year, int mon, int day) { int ret=(year-1)*365+(year-1)/4-(year-1)/100+(year-1)/400,i; //计算到公元1年1月1日 for(i=0;i<mon-1;ret+=date[leapyear(year)][i++]); //把当前的几个月的天数加上, return (ret+day)%7;//将这个月的天数加上。 }
bool check(int y,int m,int d) { if(y<=0) return false; if(m<1 || m>12) return false; if(!(d>=0 && d<=date[leapyear(y)][m-1])) return false; if(y==1752 && m==9 && (d>2 && d<14)) return false; return true; }
计算如下:
if(check(y,m,d)) { if(y<1752 || (y==1752 && m<9) || (y==1752 && m==9 && d<=2)) printf("%s %d, %d is a %s\n",month[m-1],d,y,s[g(y,m,d+11)]); else printf("%s %d, %d is a %s\n",month[m-1],d,y,s[g(y,m,d)]); }其他的就不粘了。
为什要添加这中断的11天呢,因为1752个年头其实只要是1752%4==0,就是闰年,而我们上边计算的时候,是按照现在的算法计算,而之后的闰年则是现在的算法,计算天数的时候已经把这中断的11天加上了。
好了,就这么多了。