这题太可怕了早已经放弃自己翻译,网上搜的题意
定义:
Goog month : 该月第一个工作日为星期一的月份
Luckly month: 该月最后一个工作日为星期五的月份
问: 给定一个Gregorian Calendar格里高公历的 时间闭区间(就是包括端点的年月了)
【开始年、月】~【结束年、月】
在这个时间区间内,有多少个Goog month,有多少个Luckly month
文章要点:
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为休息日
#include <stdio.h>
#define N 10001
int f[N+10][15];//f[i][j]表示到第i年第j月有多少个GoodMonth
int g[N+10][15];//g[i][j]表示到第i年第j月有多少个LuckyMonth
int leap(int y)
{
if(y==1700)
return 1;
if(y>=1582&&((y%4==0&&y%100!=0)||y%400==0))
return 1;
if(y<1582&&y%4==0)
return 1;
return 0;
}
int main()
{
int cnt=0;//记录总天数
f[0][12]=0;//记录GoodMonth的数量
g[0][12]=0;//记录LuckyMonth的数量
for(int i=1; i<=N; i++)
{
for(int j=1; j<=12; j++)
{
int t=cnt;
if(j==1)//初始化当前的GoodMonth,LuckyMonth的数量与前一个月一样,假设这个月既不是LM,GM
{
f[i][j]=f[i-1][12];
g[i][j]=g[i-1][12];
}
else
{
f[i][j]=f[i][j-1];
g[i][j]=g[i][j-1];
}
if((cnt+5)%7==6||(cnt+5)%7==5||(cnt+5)%7==0)//这个月的前一天为周五,周六,周日
f[i][j]++;
if(j==1||j==3||j==5||j==7||j==8||j==10||j==12)
{
cnt+=31;
}
else if(j==4||j==6||j==9||j==11)
{
if(i==1752&&j==9)
cnt+=19;
else cnt+=30;
}
else if(j==2)
{
if(leap(i))
cnt+=29;
else cnt+=28;
}
if((cnt+5)%7==5||(cnt+5)%7==6||(cnt+5)%7==0)//这个月的最后一天为周日周六周五
{
g[i][j]++;
}
}
}
int t,sx,sy,ex,ey;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
if(sy==1)
{
sx-=1;
sy=12;
}
else
{
sy-=1;
}
printf("%d %d\n",g[ex][ey]-g[sx][sy],f[ex][ey]-f[sx][sy]);
}
}