题目:http://cerberus.delos.com:790/usacoprob2?a=u6HWJikTmqd&S=friday
代码:
/*
ID: chicc991
PROG: friday
LANG: C++
*/
#include <fstream>
using namespace std;
int n;//输入的年份
int s[7];
void calculate()
{
int i,w,y,c;
for(i=0; i<=n-1; i++)
{
int m,k;
int d=13;//日期
y=(1900+i)%100;//年份后两位
c=(1900+i)/100;//年份前两位
if(i==(n-1)) k=12;
else k=14;
for(m=3; m<=k; m++) //月份由1-12变为3-14
{
w=y+int(y/4)+int(c/4)-2*c+int(26*(m+1)/10)+d-1;
w=(w%7+7)%7;
s[w]++;
}
}
w=99+99/4+18/4-2*18+26*(13+1)/10+13-1;
w=(w%7+7)%7;
s[w]++;
w=99+99/4+18/4-2*18+26*(14+1)/10+13-1;
w=(w%7+7)%7;;
s[w]++;
}
int main()
{
ifstream fin("friday.in");
ofstream fout("friday.out");
fin>>n;
int j;
for(j=0; j<7; j++)
s[j]=0;
calculate();
fout<<s[6]<<" ";
for(j=0; j<5; j++)
fout<<s[j]<<" ";
fout<<s[5]<<endl;//为了输出格式一致
fin.close();
fout.close();
}
1.
蔡勒公式 自行查看百度百科
2.整数取模(以模7为例)
w=(w%7+7)%7
如果改为负数时w=w%7+7,则-7,-14等情况将会被忽略。
不用蔡勒公式解法:
分析:
- 因为1900.1.1是星期一,所以1900.1.13就等于(13-1) mod7+1=星期六。这样讲可能不太清楚。那么,我来解释一下:每过7天是一个星期。n天后是星期几怎么算呢?现在假设n是7的倍数,如果n为14,那么刚好就过了两个星期,所以14天后仍然是星期一。但如果是过了15天,那么推算就得到是星期二。这样,我们就可以推导出一个公式来计算。(n天 mod 7(一个星期的天数)+ 现在日期的代号) mod 7 就等于现在日期的代号。当括号内的值为7的倍数时,其代号就为0,那么,此时就应该是星期日这样,我们可以得出题目的算法:
int a[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}
int b[8]={0}
a数组保存一年12个月的天数(因为C语言中数组起始下标为0,所以这里定义为13)。
b数组保存星期一到星期日出现的天数。用date记录目前是星期几的代号,然后用两个循环,依次加上所经过的月份的天数,就出那个月是星期几,当然,要注意判断闰年!知道了这个方法,实现起来就很容易了。
注意考虑闰月的情况。
最后注意要换行,否则会错误。
代码:
#include<fstream>
using namespace std;
int main()
{
int year,month,i,n,last=3;
int dayOfMonth[12]={31,31,28,31,30,31,30,31,31,30,31,30};
int result[7]={0};
ifstream fin("friday.in");
ofstream fout("friday.out");
fin>>n;
for(year=1900;year<1900+n;++year){
if(year%400==0||(year%100!=0&&year%4==0)) dayOfMonth[2]=29;
for(month=0;month<12;++month){
last=(last+dayOfMonth[month])%7;
result[last]++;
}
dayOfMonth[2]=28;
}
for(i=0;i<6;++i) fout<<result[(i+6)%7]<<' ';
fout<<result[5]<<endl;
fin.close();
fout.close();
return 0;
}