三部曲二(基本算法、动态规划、搜索)-1003-Lucky and Good Months by Gregorian Calendar
模拟加阅读题。。。。。。虽然很多事常识性的知识,但也有许多不知道的知识,关键是不读不知道那些是已经知道的那些不是,许多重要的信息零散的分布在一大坨英文里,读起来很痛苦。。。。。。自己读了一遍,读的晕晕乎乎的,还是看了别人的题解。
别人博客给的题意要点:
文章要点:
Gregorian Calendar格里高公历 就是现在广泛使用公历(西历),下面简称GC
GC的起始日期为 1年1月1号,该日为星期六
GC平年有365天,闰年366天(2月多1天)
GC有12个月,各月的天数和现在的使用的西历一致
GC在1582年之前(不包括1582),若该年份能被4整除,则为闰年
GC在1582年之后(包括1582),判断闰年的标准(满足下面随便一个):
(1) 能被4整除,但不能被100整除;
(2) 能被400整除。
由于历史原因,GC规定1700年无条件为闰年
由于历史原因,GC规定1752年9月3日~13日共11天不存在,即1752年9月只有19天
GC一星期有7天,排序为Sun,Mon,Tue,Wed,Thu,Fri,Sat,和现在的星期一致,其中Mon到Fri为工作日,Sun和Sat为休息日
我自己的解题思路:
这道题是一道模拟题,不难想,不过需要细心,一点不对就会WA。
先算每年第一天是从1年1月1日后的第几天,再算具体到某年某月的第一天是从1年1月1日后的第几天,若是第n天,如果n%7<=2的话,就说明是Good Month,如果这一月是Good Month,上一月一定是 Lucky Month。
#include <iostream> #include <cstring> #include <stdio.h> #define maxn 10001 using namespace std; int ys,ms,ye,me,days[maxn],bgday[maxn]; int months[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; bool IsLeapYear(int year) { if(year==1700) return true; else if(year<1582) { if(year%4==0) return true; else return false; } else if(year>=1582) { if((year%100!=0&&year%4==0)||year%400==0) { return true; } else return false; } } void CountDays() { int i; for(i=1;i<10001;i++) { if(IsLeapYear(i)) { days[i]=366; } else days[i]=365; if(i==1752) days[i]-=11; bgday[i+1]=bgday[i]+days[i]; } } int main() { //// freopen("in.txt","r",stdin); bgday[1]=0; CountDays(); int i,j; //// for(i=1;i<100;i++) //// { //// cout<<days[i]<<'\t'<<bgday[i]<<'\t'; //// if(i%5==0) //// cout<<endl; //// } int T; scanf("%d",&T); while(T--) { int lm=0,gm=0; scanf("%d%d%d%d",&ys,&ms,&ye,&me); int td=bgday[ys]; for(i=1;i<ms;i++) { td+=months[i]; if(i==2&&IsLeapYear(ys)) td++; if(i==9&&ys==1752) td-=11; } i=ys; j=ms; me++; if(me>12) { ye++; me=1; } while(!(i==ye&&j==me)) { // cout<<td<<' '<<td%7<<endl; // cout<<td<<endl; if(td%7<=2) { gm++; if(!(i==ys&&j==ms)) lm++; } td+=months[j]; if(j==2&&IsLeapYear(i)) td++; if(i==1752&&j==9) td-=11; j++; if(j>12) { i++; j=1; } } if(j==2&&IsLeapYear(i)) td++; if(i==1752&&j==9) td-=11; // cout<<td<<endl; if(td%7<=2) lm++; printf("%d %d\n",lm,gm); } return 0; }