模拟/USACO 1.1.3 Friday the Thirteenth
题意:给出一个数n,求出从1900~1900+n-1之中,在13号的周一、周二、.....、周日各有几天。
分析:对于年月日有个计算公式,叫蔡勒公式,详见百度百科。
这里没有用这个公式。先提前开个数组month记录每个月的天数备用,至于2月份,可以根据闰年计算法则:四年一闰,百年不闰,四百年一闰,在单独处理2月的情况。再开个数组week记录答案。用一个变量last表示当前是这个月的1号是第多少天,初始为1,则一上来+12表示这个月的13号,mod 7则能计算出此时为周几,计入答案。再根据是否为闰年的二月来把last加至下个月的一号。以此类推,两重循环(一重循环year,一重循环month)即可。
注意输出,先输出周六周日,再是周一~周五。不要忘记usaco末尾坑爹的换行。
1 #include<cstdio> 2 #include<cstring> 3 4 int month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; 5 6 int week[8]; 7 int leap(int x) 8 { 9 if((x%4==0 && x%100!=0)||(x%400==0)) return 1; 10 return 0; 11 } 12 int main() 13 { 14 freopen("friday.in","r",stdin); 15 freopen("friday.out","w",stdout); 16 17 memset(week,0,sizeof(week)); 18 int n; 19 scanf("%d",&n); 20 int last=1; 21 for(int i=0;i<n;++i) 22 { 23 for(int j=1;j<=12;++j) 24 { 25 last+=12; 26 week[last%7]++; 27 if(j==2 && leap(1900 + i)) last+=29-12; 28 else last+=month[j]-12; 29 } 30 } 31 printf("%d %d %d %d %d %d %d\n",week[6],week[0],week[1],week[2],week[3],week[4],week[5]); 32 return 0; 33 }
两次交过,第一次搞错计算方法,竟然还过了2个点..