《星期几》 蓝桥杯复赛试题
题目描述
【结果填空】 (满分5分)
1949年的国庆节(10月1日)是星期六。
今年(2012)的国庆节是星期一。
那么,从建国到现在,有几次国庆节正好是星期日呢?
只要答案,不限手段!
可以用windows日历,windows计算器,Excel公式,。。。。。
当然,也可以编程!
不要求写出具体是哪些年,只要一个数目!
千万不要提交源代码!
思路分析
这不是一道存粹的编程题目,作为一道填空题目,也不会有负责的数据结构,我们结合数学,分布解决之。
对于星期几,这明显是一个周期函数,即:f(x+T) = f(x) 其中,T = 7.
一个很直接的思路就是:用from 1940-10-1 to year-10-1的天数除以7,如果余数为1,则该年的国庆节是星期天。
即:f(6 + n*T + 1) = f(7)
但是,该方法有一个明显的缺点就是要计算n*T并不是很简单,而且随着年份的增大,这个数字也会越来越大,直到不能存储,所以需要进行优化。
优化的思路很简单,其实我们没有必要揪着1949年的国庆节不放,假设我们知道2000年的某一天使星期几的话,我们还用减去1949年的国庆节吗?很明显不用,这就是优化的原理。
假设赵国庆出生于1949年10月1日,那么他到1950年10月1日的时候,是不是该过生日了?哈哈,没错,正好一年!那么这一年是365还是366天呢?这取决是1950年是平年还是闰年。
1949年的国庆假是星期六,即:f(6)
设这一年的总天数为x,则若x为平年,则x=365,若x为闰年,则y=366.
算到这里,我们需要一个判断平年闰年的函数:
int judge(int year) //用于判断平年,闰年的函数 { if(year%400==0 || year%4==0 && year%100 !=0) { return 366; } else { return 365; } }
x / 7 = a ……b;
对于1949年的国庆节,f = f( t1949 ) = f(6)
对于1950年的国庆节,f = f(t1950) = f(t1949 + a*T +b) = f( (t1949+b)%7 )
对于1951年的国庆节,f = f(t1951) = f(t1950 + a*T +b) = f( (t1950+b)%7 )
……
得到一般结论f = f(tyear) = f(t(year-1) + a*T + b) = f( (t(year-1) + b)%7)
编写代码
#include<iostream> using namespace std; int judge(int year) //用于判断平年,闰年的函数 { if(year%400==0 || year%4==0 && year%100 !=0) { return 366; } else { return 365; } } int main() { int counter = 0; int w = 6; for(int year=1950;year<2013;year++) { w = (judge(year)%7 + w)%7 ; if(0 == w) { //cout<<year<<endl; counter++; } } cout<<counter<<endl; return 0; }
说明:
1961
1967
1972
1978
1989
1995
2000
2006
9