CODE【VS】1384 黑色星期五(计算某一天是星期几的公式)

题目描述 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 Input

20

样例输出 Sample Output

36 33 34 33 35 35 34

数据范围及提示 Data Size & Hint

n是一个非负数且不大于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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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;
}



你可能感兴趣的:(数学)