HDU 6112 今夕何夕 (日历题 Zeller公式 2017百度之星初赛A第五题)

来源:互联网 发布:火柴人动图制作软件 编辑:程序博客网 时间:2024/05/18 17:56

题目链接

HDU6112

题目大意

输入一个日期:YYYY-MM-DD
求接下来最近的哪一年里的同一个日子,和今天的星期数一样。

分析

  • 应用Zeller公式,可以计算1582年10月4日后任一日期的星期。

  • 解决了这个问题后,只需枚举之后的每一年的同一日期,找到最近的星期数相同的即可。

  • 但这道题这样解的话要注意一个坑点,如果输入的日期为闰年的2月29号,不能直接+1枚举以后的年份,因为平年根本就没有2月29号,因此可以加4枚举。但+4也不一定是闰年,因此每次再判断一下枚举的年份是否为闰年。我因为这些原因WA了两次 QAQ

  • 所以做日历题一定要特别小心闰年这个存在啊!!!

代码

#include <bits/stdc++.h>using namespace std;const double pi=4*atan(1.0);bool is_reapyear(int y){    if (((y%4==0)&&(y%100!=0))||(y%400==0))        return true;    else        return false;}int Zeller(int year,int month,int day)///蔡勒公式算星期{    if (month==1||month==2)    {        year--;        month+=12;    }    int c=year/100;    int y=year-c*100;    int week=(c/4)-2*c+(y+y/4)+(13*(month+1)/5)+day-1;    while(week<0){week+=7;}    week%=7;    return week;}int main(){    int year,month,day,T;    char ch[15];    scanf("%d",&T);    while (T--)    {        scanf("%s",ch);        year=(ch[0]-48)*1000+(ch[1]-48)*100+(ch[2]-48)*10+(ch[3]-48);        month=(ch[5]-48)*10+(ch[6]-48);        day=(ch[8]-48)*10+(ch[9]-48);        int week=Zeller(year,month,day);        int week2;        if (month==2&&day==29)///如果输入为闰年的2月29号        {            for (int i=year+4;i<=9999;i+=4)//每四年枚举            {                if (!is_reapyear(i)) continue;//不是闰年就PASS                week2=Zeller(i,month,day);                if (week==week2)                {                    printf("%d\n",i);                    break;                }            }        }        else        {            for (int i=year+1;i<=9999;i++)            {                week2=Zeller(i,month,day);                if (week==week2)                {                    printf("%d\n",i);                    break;                }            }        }    }    return 0;}
阅读全文
0 0