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

题目链接

HDU6112

题目大意

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

分析

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

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

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

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

代码

#include 
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;
}

你可能感兴趣的:(2017百度之星初赛)