文章要点:
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;
}