题目:
众所周知,13是个神奇的数字。在中国代表吉祥,而在西方代表邪恶。小南突然想知道,在星期六、星期日、星期一到星期五中,每月的13号是星期几的次数最多?这个统计从1900年1月1日到1900+n-1年12月31日,其中1≤n≤400。聪明的你能帮小南写一个程序来计算在n年里每月13日落在星期一、星期二、……、星期日的次数吗?
说明:
(1) 1900年1月1日是星期一。
(2) 4,6,11和9月有30天。其他月份除了2月有31天。闰年2月有29天,平年2月有28天。
(3) 年份可以被4整除并且不能被100整除,或者能够被400整除,那么该年为闰年。例如,1992=4*498 所以 1992年是闰年,但是1990年不是闰年。1700,1800,1900和2100年是平年,而2000年是闰年。
输入:
多组样例。每组样例输入占一行,包含一个正整数n,表示为从1900之后的n年。
输出:
对于每组样例,输出一行7个整数,整数之间用一个空格分隔,它们代表13日是星期六,星期日,星期一,……,星期五的次数。
样例输入:20
样例输出:36 33 34 33 35 35 34
————————————————————————————————————————————————————————————————————————————
分析: 对这道题目进行简单拆分,可以分作 1.一个求得每月13号为周几的程序 2. 一个记录周一到周日出现次数的程序。
第二个程序很简单,用一个数组很容易就是实现了,难的是第一个程序,有人可能通过求每一个月的13号与1990年1月1日的天数间隔再%7来求得对应的日子,由于是整年整年算,这确实不难。
int get_day(int n)
{
int day=0;
n+=1899;
for(;n>=1900;n--)
{
if(n/4==0&&n/100!=0||(n/400==0))
{
day+=366;
}
else
{
day+=365;
}
}
return day;
}
但我这里介绍的是以上个月的十三号推导下个月的13号。
由于一个星期的长度总是7天,那只要我们知道了上个13号对应的星期,再知道这个月13日到下个月13日的天数,那我们就能求得下个月13号对应的星期;
经过简单的推导,能得到对应关系如图
月的天数 | 上个月13号对应的星期 | 本月13号对应的星期 |
28 | x | x |
29 | x | x+1(若>7,则减7) |
30 | x | x+2(若>7,则减7) |
30 | x | x+3(若>7,则减7) |
再对每个月的天数进行判定,就能得到程序,最后与第二个程序整合,得到最终程序
#include <stdio.h>
int main()
{
int n;
int last;
while(scanf("%d",&n)!=EOF)
{
last=2;
int day[7]={0};
for(int i=1900;i<=1900+n-1;i++)
{
for(int j=1;j<=12;j++)
{
if(j==2||j==4||j==6||j==8||j==9||j==11||j==1)
{
if(last+3<7)
{
day[last+3]++;
last+=3;
}
else
{
day[last+3-7]++;
last=last+3-7;
}
}
else if(j==3)
{
if(i%400==0||(i%4==0&&i%100!=0))
{
if(last+1<7)
{
day[last+1]++;
last+=1;
}
else
{
day[last+1-7]++;
last=last+1-7;
}
}
else
{
day[last]++;
}
}
else{
if(last+2<7)
{
day[last+2]++;
last+=2;
}
else
{
day[last+2-7]++;
last=last+2-7;
}
}
}
}
printf("%d %d %d %d %d %d %d\n",day[5],day[6],day[0],day[1],day[2],day[3],day[4]);
}
}