An problem about date

题目链接:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=219

An problem about date

时间限制:2000 ms  |  内存限制:65535 KB
难度:2
描述

acm的iphxer经常忘记某天是星期几,但是他记那天的具体日期,他希望你能写个程序帮帮他。

 

输入
每行有三个整数 year,month,day,日期在1600年1月1日到9600年1月1日之间;
输出
输出对应的星期,用一个整数表示;(星期一到星期六用1-6表示,星期日用0表示)
样例输入
2011 3 6
1949 10 1
2011 4 1
1945 8 15
样例输出
0
6
5
3

分析:如果用普通的方法,即初学的时候方法,算出输入的日期到1600年1月1日之间有几天然后%7找到对应的星期几,但这种方法会超时。因此我们要懂得变通,用吉姆拉尔森公式可以直接求出具体那一天的星期

这是百度上的,原谅我比较懒,直接复制过来了

基姆拉尔森计算公式(C++与VB.Net整数除法和取余运算符不同)
W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7 //C++计算公式//d表示日期中的日数,m表示月份,y表示年份
W = (D + 2 * M + 3 * (M + 1) \ 5 + Y + Y \ 4 - Y \ 100 + Y \ 400) Mod 7 'VB.Net计算公式
在公式中d表示日期中的日数,m表示月份数,y表示年数。
注意:在公式中有个与其他公式不同的地方:
把一月和二月看成是上一年的十三月和十四月,例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。

下面这个代码是普通的方法(会超时)的做法:


#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int pan(int x)//判断这一年是否是闰年
{
    if((x%4==0&&x%100)||x%400==0)
        return 1;
    return 0;
}
int main()
{
    int a,b,c;
    int s[]={0,31,30,31,30,31,30,31,31,30,31,30,31};//为了让月份和这个月份的天数转化方便,让s[0]=0,从s[1]开始,代表,某月天数是多少天
    while(~scanf("%d %d %d",&a,&b,&c))
    {
        int ans=c;
        for(int i=1600;i<a;i++)
        {
            if(pan(i))//整年的天数计算
                ans+=366;
            else
                ans+=365;
        }
        for(int i=1;i<b;i++)整月的计算
        {
            if(i==2)
            {
                if(pan(a)) ans+=29;
                else ans+=28;
            }
            else
                ans+=s[i];
        }
        ans=(ans+5)%7;//加5可以让星期日输出是0
        printf("%d\n",ans);
    }
}

下面的代码是用公式的方法:

#include<stdio.h>
int fun(int a,int b,int c)
{
    if(b<3)
    {
        b+=12;
        --a;
    }
    return (c+2*b+3*(b+1)/5+a+a/4-a/100+a/400+1)%7;//加1是为了让星期日输出是0
}
int main()
{
    int a,b,c;
    while(~scanf("%d%d%d",&a,&b,&c))//a是年份,b是月份,c是天数
    {
        printf("%d\n",fun(a,b,c));
    }
}

发布了39 篇原创文章 · 获赞 3 · 访问量 5556
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览