题目大意:统计从1900年1月1号开始的n年时间内,每个月的13号落在星期一、星期二、星期三……星期日的次数。
分析:从今年某个月的13号到明年那个月的13号经过的时间恰好是一年,经过的天数可能是365或366,从今年的1月13到明年的1月13经过的天数是由今年的二月份的天数决定的,也就是由今年是否是闰年决定的,2月也是一样,但从今年的3月13到明年的3月13经过的天数是由明年的二月份的天数决定的,也即由明年是否是闰年决定,4、5、6、……12月也一样。
365%7=1
366%7=2
知道了以上2个算式,便可以从今年每月13的星期数推得明年的每月13的星期数,以后n年的都可以推出。递推的初始边界为1900年每月13的星期数,可由题中信息得出,也可查阅日历……

/* ID: lijian42 LANG: C++ TASK: friday */ #include <stdio.h> #include <string.h> int d[12]; int cnt[7]; void init() { d[0]=6; d[1]=2; d[2]=2; d[3]=5; d[4]=0; d[5]=3; d[6]=5; d[7]=1; d[8]=4; d[9]=6; d[10]=2; d[11]=4; } bool IsLeap(int k) { if(k%400==0 || k%4==0 && k%100!=0) return true; return false; } void tran(int k) { if(IsLeap(k)) for(int i=0;i<2;i++) d[i]=(d[i]+1)%7; if(IsLeap(k+1)) for(int i=2;i<12;i++) d[i]=(d[i]+1)%7; for(int i=0;i<12;i++) d[i]=(d[i]+1)%7; } int main() { freopen("friday.in","r",stdin); freopen("friday.out","w",stdout); int n,i,j; int test=0; while(~scanf("%d",&n)) { memset(cnt,0,sizeof(cnt)); init(); for(i=0;i<n;i++) { for(j=0;j<12;j++) cnt[d[j]]++; tran(1900+i); } printf("%d",cnt[6],cnt[0]); for(i=0;i<6;i++) printf(" %d",cnt[i]);puts(""); } return 0; }