CODE【VS】1384 黑色星期五(計算某一天是星期幾的公式)
阿新 • • 發佈:2019-01-09
題目描述 Description
13號又是星期五是一個不尋常的日子嗎?
13號在星期五比在其他日少嗎?為了回答這個問題,寫一個程式來計算在n年裡13
日落在星期一,星期二......星期日的次數.這個測試從1900年1月1日到
1900+n-1年12月31日.n是一個非負數且不大於400.
這裡有一些你要知道的:
1900年1月1日是星期一. |
4,6,11和9月有30天.其他月份除了2月有31天.閏年2月有29天,平年2月有28天. |
年份可以被4整除的為閏年(1992=4*498 所以 1992年是閏年,但是1990年不是閏年) |
以上規則不適合於世紀年.可以被400整除的世紀年為閏年,否則為平年.所以,1700,1800,1900和2100年是平年,而2000年是閏年. |
請不要預先算好資料!
輸入描述 Input Description一個整數n.
輸出描述 Output Description七個在一行且相分開的整數,它們代表13日是星期六,星期日,星期一.....星期五的次數.
樣例輸入 Sample Input20
樣例輸出 Sample Output36 33 34 33 35 35 34
資料範圍及提示 Data Size & Hintn是一個非負數且不大於400.
題解:這道題的話,我感覺直接從1900年到給定的那個年份跑一遍,暴力可以求出來。應該不會超時。這裡我用的不是暴力。是一個叫基姆拉爾森計算公式:W = (d+2*m+3*(m+1)/5+(y)+(y)/4-(y)/100+(y)/400)%7; 在公式中d表示日期中的日數+1,m表示月份數,y表示年份。
注意:用該公式時,需要把一月和二月看成是上一年的十三月和十四月,公式中的d是日期加1.所以計算結果就是實際的星期,即是:“1”為星期一,“2”為星期二。。。。“0”為星期日。
還有另外一個公式:W = (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7 (其中y是四位數的,如2009。)
注意:該公式中同樣要把1月和2月分別當成上一年的13月和14月處理。而且該公式的“0”為星期一,。。。。,“6”為星期日。
附上程式碼:
#include<cstdio> #include<cstring> #include<cmath> #include<climits> #include<iostream> #include<algorithm> #include<vector> #include<string> #include<map> #include<queue> #include<stack> using namespace std; int main() { int n; scanf("%d", &n); int week[10] = {0}; for(int i = 1900; i < 1900+n; i++) { for(int j = 1; j < 13; j++) { int m, W; if(j == 1 || j == 2) { m = j+12; W = (14+2*m+3*(m+1)/5+(i-1)+(i-1)/4-(i-1)/100+(i-1)/400)%7; // 基姆拉爾森計算公式 } else { m = j; W = (14+2*m+3*(m+1)/5+(i)+(i)/4-(i)/100+(i)/400)%7; // 基姆拉爾森計算公式 } week[W]++; } } printf("%d %d %d %d %d %d %d\n", week[6], week[0], week[1], week[2], week[3], week[4], week[5]); return 0; }