试题 算法训练 黑色星期五
资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
有些西方人比较迷信,如果某个月的13号正好是星期五,他们就会觉得不太吉利,用古人的说法,就是“诸事不宜”。请你编写一个程序,统计出在某个特定的年份中,出现了多少次既是13号又是星期五的情形,以帮助你的迷信朋友解决难题。
说明:(1)一年有365天,闰年有366天,所谓闰年,即能被4整除且不能被100整除的年份,或是既能被100整除也能被400整除的年份;(2)已知1998年1月1日是星期四,用户输入的年份肯定大于或等于1998年。
输入格式:输入只有一行,即某个特定的年份(大于或等于1998年)。
输出格式:输出只有一行,即在这一年中,出现了多少次既是13号又是星期五的情形。
输入输出样例
样例输入
1998
样例输出
3
思路:看读完题目我们可以看到需要解决两个问题,第一每年份的开头是星期几;第二就是统计十二个月中十三号是星期五的有几天,再输出即可。
刚开始觉得求每年开头是星期几有点麻烦,于是查了一下有没有其他的好办法,看到一个公式是求的比较快的(在文章下面会有公式),但是和我的思路不符合就没有采用了,再一想发现用取余可以很快求得,再算成十三号同时是星期五就比较容易了。
代码如下:
#include<stdio.h>
int main(){
int a[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int n,i,j,k=3,l,s=0;
scanf("%d",&n);
for(i=1998;i<n;i++){
if((i%4==0 && i%100!=0) || i%400==0){
j=366;
}
else{
j=365;
}
k=7-k;
k=(j-k)%7;
}
if((n%4==0 && n%100!=0) || n%400==0){
a[2]=a[2]+1;
}
for(l=1;l<=12;l++){
for(j=1;j<=a[l];j++){
k++;
if(j==13 && k==5){
s++;
}
if(k>=7){
k=0;
}
}
}
printf("%d",s);
return 0;
}
我写的代码可能比较长,所以利用公式简单的代码我还是自己写出来分享:公式为: d= (a+2b+3(b+1)/5+c+c/4-c/100+c/400)%7+1(a为日期,b为月份,c为年份) ,名叫基姆拉尔森计算公式,但是使用公式的前提是一年得有十四个月份,多出来两个月份是下一年的补上来的。
代码也是如下:
#include<stdio.h>
int main(){
int sum=0,a,b,c,i,d,c1,b1;
scanf("%d",&c);
a=13; //设日期为十三日;
for(i=1;i<=12;i++){
if(i==1 || i==2){
b1=i+12;
c1=c-1;
d=(a+2*b1+3*(b1+1)/5+c1+c1/4-c1/100+c1/400)%7+1;
}
else{
b=i;
d=(a+2*b+3*(b+1)/5+c+c/4-c/100+c/400)%7+1;
}
if(d==5){
sum++;
}
}
printf("%d",sum);
return 0;
}