在西方,星期五和数字 13 都代表着坏运气,两个不幸的个体最后结合成超级不幸的一天。所以,不管哪个月的十三日又恰逢星期五就叫“黑色星期五”。
要求:输入年份,输出是:判断该年是否包含黑色星期五,如包含,给出具体日期
蔡勒(zeller)公式:随便给一个日期,就能用这个公式推算出是星期几
W = [C/4] - 2C + y + [y/4] + [13 * (M+1) / 5] + d - 1
(或者是:w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1)
若要计算的日期是在1582年10月4日或之前,公式则为
w=y+[y/4]+[c/4]-2c+[13(m+1)/5]+d+2
w:星期; w对7取模得:0-星期日,1-星期一,2-星期二,3-星期三,4-星期四,5-星期五,6-星期六
c:世纪(前两位数)
y:年(后两位数)
m:月(m大于等于3,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年的13、14月来计算,比如2003年1月1日要看作2002年的13月1日来计算)
d:日
利用泰勒公式求某一天是星期几:
#include<iostream>
#include<string>
using namespace std;
int main(){
int y,m,d,w;
while(cin>>y>>m>>d){
int c=y/100;
y=y-100*c;
if(m<3){
m+=12;
y-=1;
}
w=c/4-2*c+y+y/4+13*(m+1)/5+d-1;
while(w<0) w+=7;
w%=7;
}
string week[7]= {"sunday","monday","tuesday","wednesday","thursday","friday","saturday"};
cout<<week[w]<<endl;
}
利用蔡勒公式求特定年份有没有黑色星期五:
#include <iostream>
using namespace std;
int main()
{ int friday(int,int,int);
int y,m,d=13,w;
cout<<"input a year:"<<endl;
cin>>y;
int cont=0;
for(m=1;m<13;++m){
if(friday(y,m,d))
cout<<"dark friday:"<<m<<"\t"<<d<<"\t"<<endl;
cont++;
}
return 0;
}
int friday(int y,int m,int d){ //利用蔡勒公式
int c=y/100;
y=y-100*c;
int w;
if(m<3){ //1,2月被看作上一年的13,14月
m+=12;
y-=1;
}
w=c/4-2*c+y+y/4+13*(m+1)/5+d-1;
while(w<0) w+=7;
w%=7;
if(w==5)
return 1;
else return 0;
}
还可以检测是不是每一年都有黑色星期五:
#include<iostream>
using namespace std;
int friday(int,int,int);
int main(){
int y,m,d=13;
for(y=0000;y<2013;++y){
int cont=0;
int year=y;
for(m=1;m<13;++m){
if(friday(y,m,d))
cont++;
}
if(cont==0)
cout<<year<<"年没有黑色星期五"<<endl;
}
}
int friday(int y,int m,int d){ //利用蔡勒公式
int c=y/100;
y=y-100*c;
int w;
if(m<3){ //1,2月被看作上一年的13,14月
m+=12;
y-=1;
}
w=c/4-2*c+y+y/4+13*(m+1)/5+d-1;
while(w<0) w+=7;
w%=7;
if(w==5)
return 1;
else return 0;
}
经检测,从公元0
年开始,确实是
每一年都有黑色星期五。
如果不用蔡勒公式,那就比较复杂了,首先看当年有没有闰年。
求闰年的简单程序,计算显示出0~2012年的闰年:
#include <iostream>
using namespace std;
int leapyear(int);
int main()
{
int cont=0;
for(int year=0;year<2013;++year){
if(leapyear(year)){
cout<<year<<"\t";
cont++;
if(cont%5==0)
cout<<endl;
}
}
return 0;
}
int leapyear(int year){
if((year%400==0) || (year%100!=0) && (year%4==0))
return 1;
else
return 0;
}
要计算那一天是星期几,还可以用这样的式子:
闰年时((year-1)*365+(year-1)/4-year/100+year/400+b[i]+1)%7==5
平年时((year-1)*365+year/4-year/100+year/400+a[i]+1)%7==5
其中a[i]和b[i]指的是该年1号到现在的天数(正如下面程序所示),这是因为我们知道公元1年1月1日是星期一。
利用这个leapyear的子程序,求黑色星期五:
#include<iostream>
using namespace std;
int leapyear(int);
typedef struct
{
int month;
int day;
}Data;
int main()
{
Data data[12]; //存放特定年份的黑色星期五的日期,个数不可能超过12个
int a[13]={0,12,43,71,102,132,163,193,224,255,285,316,346};
int b[13]={0,12,43,72,103,133,164,194,225,256,286,317,347};//闰年时
int n=0,i,year;
cin>>year;
if(leapyear(year))//闰年时
{
for(i=1;i<=12;i++)
{
if(((year-1)*365+(year-1)/4-year/100+year/400+b[i]+1)%7==5)
{
data[n].month=i;
data[n].day=13;
n++;
}
}
}
else//平年
{
for(i=1;i<=12;i++)
{
if(((year-1)*365+year/4-year/100+year/400+a[i]+1)%7==5) //计算公元到现在一共多少天
//公元1年1月1日是星期一
{
data[n].month=i;
data[n].day=13;
n++;
}
}
}
if(n==1)
{
cout<<"There is "<<n<<" Black Friday in year "<<year<<endl<<"It is ";
cout<<year<<"."<<data[0].month<<"."<<data[0].day<<endl;
}
else
{
cout<<"There is "<<n<<" Black Friday in year "<<year<<endl<<"They are "<<endl;;
for(i=0;i<n;i++) cout<<year<<"."<<data[i].month<<"."<<data[i].day<<endl; ;
}
return 0;
}
int leapyear(int year){
if((year%400==0) || (year%100!=0) && (year%4==0))
return 1;
else
return 0;
}