文章要点:
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天
#include <cstdio> int mon[] = {0,31,28,31,30,31,30,31,31,30,31,30,31},sg,sl; unsigned long long sd; int judge(int y) { if(y == 1752) mon[9] = 19; else mon[9] = 30; if(y == 1700) return 1; if(y < 1582) { if(y%4 == 0) return 1; return 0; } if( (y%4 == 0 && y%100 != 0) || y%400 == 0) return 1; return 0; } void counter(int from,int endd) //只需要判断月末是否为周五到周天之一,如果是则本月为lucky,则下个月则为good,endd月只算月尾 { for(int i = from; i <= endd; i++) { if((sd+5)%7 == 0 || (sd+5)%7 == 6 || (sd+5)%7 == 5) sg++; sd += mon[i]; if((sd+5)%7 == 0 || (sd+5)%7 == 6 || (sd+5)%7 == 5) sl++; } } int main() { int T,i,j,ys,ms,ye,me; scanf("%d",&T); while(T--) { scanf("%d %d %d %d",&ys,&ms,&ye,&me); sd = 0; sl = 0; sg = 0; for(i = 1; i < ys; ++i) { if(judge(i)) sd += 366; else sd += 365; if(i == 1752) sd -= 11; } mon[2]=(judge(ys)==1?29:28); for(i = 1; i < ms; i++) sd += mon[i]; if( (sd+5)%7==0||(sd+5)%7==6||(sd+5)%7==5 ) sg++; sd+=mon[ms]; if( (sd+5)%7==0||(sd+5)%7==6||(sd+5)%7==5 ) sl++; if(ys == ye) counter(ms+1,me); else { counter(ms+1,12); for(j=ys+1;j<ye;j++) { mon[2]=(judge(j)==1?29:28); counter(1,12); } mon[2]=(judge(ye)==1?29:28); counter(1,me); } printf("%d %d\n",sl,sg); } return 0; }