題目: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;
}