题目描述
有些西方人比较迷信,如果某个月的13号正好是星期五,他们就会觉得不太吉利,用古人的说法,就是“诸事不宜”。请你编写一个程序,统计出在某个特定的年份中,出现了多少次既是13号又是星期五的情形,以帮助你的迷信朋友解决难题。
说明:(1)一年有365天,闰年有366天,所谓闰年,即能被4整除且不能被100整除的年份,或是既能被100整除也能被400整除的年份;(2)已知1998年1月1日是星期四,用户输入的年份肯定大于或等于1998年。
输入
输入只有一行,即某个特定的年份(大于或等于1998年)。
输出
输出只有一行,即在这一年中,出现了多少次既是13号又是星期五的情形
样例输入
1998
样例输出
3
分析
方法一 :暴力法
第一种方法是用正常的思路,判断这一年每月13号是否为星期五,那么怎么才能判断这一天是星期五呢,我们知道,1月1日是星期四,那么1月2日就是星期五,以后每隔七天又是星期五。因此如果天数对7求余等于2,那么这一天就是星期五。
那么又有一个问题了?我们怎样求天数。比如,2020年2月13日距1998年1月1日有多少天,只要求出天数,这个问题就解决了。我们可以直接暴力解决,用for循环将每一年的天数相加,注意不要加上你所求的这一年,因为我们就是要统计这一年黑色星期五的次数。
#include
int main (void){
int year;
scanf("%d",&year);
int i,j;
int tab[2][13]={
{0,31,28,31,30,31,30,31,31,30,31,30,31},//非闰年
{0,31,29,31,30,31,30,31,31,30,31,30,31},//闰年
};
int day=0,flag;
for(i=1998;i<year;i++){
flag=((i%4==0&&i%100!=0) || (i%400==0));//判断闰年
if(flag){
day+=366;
}
else{//计算所求年之前所有的天数
day+=365;
}
}
flag=((year%4==0&&year%100!=0) || (i%400==0));//判断所求这一年是否为闰年
int count=0;
for(i=1;i<13;i++){
day+=tab[flag][i-1];//加上上一月的天数
if((day+13)%7==2){//判断是否为黑色星期五
count++;
}
}
printf("%d",count);
return 0;
}
方法二 :基姆拉尔森计算公式
week=(d+2m+3(m+1)/5+y+y/4-y/100+y/400+1)%7;
可以直接计算一个日期是星期几,这样就方便多了。
在公式中d表示日期中的日数,m表示月份数,y表示年数。
注意:在公式中有个与其他公式不同的地方:
把一月和二月看成是上一年的十三月和十四月,例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。
此公式的推导此处不详细解释,读者如感兴趣,可自行百度。
百度百科中关于基姆拉尔森计算公式的介绍
知道了这个公式后,此题是不是变得更简单了呢?话不多说,代码如下。
参考代码
#include
int main (void){
int d=13,m,y,year;
scanf("%d",&year);
int i,count=0,week;
for(i=1;i<=12;i++){
y=year;
m=i;
if(m==1||m==2){//一月二月时月份与年份都会发生变化
m+=12;//因此定义两个新变量y,m
y--;
}
week=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%7;
if(week==5){
count++;
}
}
printf("%d",count);
return 0;
}
如有错误之处,敬请指正!!!