日期题——神秘13号——个人解析

题目:

众所周知,13是个神奇的数字。在中国代表吉祥,而在西方代表邪恶。小南突然想知道,在星期六、星期日、星期一到星期五中,每月的13号是星期几的次数最多?这个统计从1900年1月1日到1900+n-1年12月31日,其中1≤n≤400。聪明的你能帮小南写一个程序来计算在n年里每月13日落在星期一、星期二、……、星期日的次数吗? 
说明:
(1) 1900年1月1日是星期一。
(2) 4,6,11和9月有30天。其他月份除了2月有31天。闰年2月有29天,平年2月有28天。
(3) 年份可以被4整除并且不能被100整除,或者能够被400整除,那么该年为闰年。例如,1992=4*498 所以 1992年是闰年,但是1990年不是闰年。1700,1800,1900和2100年是平年,而2000年是闰年。

输入:

多组样例。每组样例输入占一行,包含一个正整数n,表示为从1900之后的n年。

输出:

对于每组样例,输出一行7个整数,整数之间用一个空格分隔,它们代表13日是星期六,星期日,星期一,……,星期五的次数。

样例输入:20

样例输出:36 33 34 33 35 35 34

————————————————————————————————————————————————————————————————————————————

分析: 对这道题目进行简单拆分,可以分作  1.一个求得每月13号为周几的程序  2. 一个记录周一到周日出现次数的程序。

第二个程序很简单,用一个数组很容易就是实现了,难的是第一个程序,有人可能通过求每一个月的13号与1990年1月1日的天数间隔再%7来求得对应的日子,由于是整年整年算,这确实不难。

int get_day(int n)
{
    int day=0;
    n+=1899;
    for(;n>=1900;n--)
    {
        if(n/4==0&&n/100!=0||(n/400==0))
        {
            day+=366;
        }
        else
        {
            day+=365;
        }
    }
    return day;
}

但我这里介绍的是以上个月的十三号推导下个月的13号。

由于一个星期的长度总是7天,那只要我们知道了上个13号对应的星期,再知道这个月13日到下个月13日的天数,那我们就能求得下个月13号对应的星期;

经过简单的推导,能得到对应关系如图

月的天数上个月13号对应的星期本月13号对应的星期
28xx
29xx+1(若>7,则减7)
30xx+2(若>7,则减7)
30xx+3(若>7,则减7)

再对每个月的天数进行判定,就能得到程序,最后与第二个程序整合,得到最终程序

#include <stdio.h>
int main()
{
    int n;
    int last;
    while(scanf("%d",&n)!=EOF)
    {
        last=2;
        int day[7]={0};
        for(int i=1900;i<=1900+n-1;i++)
        {
            for(int j=1;j<=12;j++)
            {
                if(j==2||j==4||j==6||j==8||j==9||j==11||j==1)
                {
                    if(last+3<7)
                    {
                        day[last+3]++;
                        last+=3;
                    }
                    else
                    {
                        day[last+3-7]++;
                        last=last+3-7;
                    }
                }
                else if(j==3)
                {
                    if(i%400==0||(i%4==0&&i%100!=0))
                    {
                        if(last+1<7)
                    {
                        day[last+1]++;
                        last+=1;
                    }
                    else
                    {
                        day[last+1-7]++;
                        last=last+1-7;
                    }
                    }
                    else
                    {
                        day[last]++;
                    }
                }
                else{
                    if(last+2<7)
                    {
                        day[last+2]++;
                        last+=2;
                    }
                    else
                    {
                        day[last+2-7]++;
                        last=last+2-7;
                    }
                }
            }

        }
        printf("%d %d %d %d %d %d %d\n",day[5],day[6],day[0],day[1],day[2],day[3],day[4]);
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值