1 条题解
-
0
解题思路
-
闰年判断:
- 对于年份 ( y < 1582 ),能被4整除即为闰年。
- 对于,且,需满足:能被4整除且不能被100整除,或能被400整除。
- 特殊处理:1700年视为闰年。
-
日期计算:
- 计算从公元1年1月1日到目标日期的总天数,用于推导星期几。
- 处理1752年9月的11天跳变:当年份大于1752或等于1752且月份大于9时,总天数需减去11天。
-
星期推导:
- 假设公元1年1月1日为星期六(代码中通过偏移量
+5
调整),通过总天数模7计算实际星期。 - 第一个工作日为周一的条件:该月1日为周一到周五中的某一天,且1日为周一(需结合星期计算)。
- 最后一个工作日为周五的条件:需判断该月最后一天的工作日是否为周五(即最后一天为周五或周六、周日需跳过)。
- 假设公元1年1月1日为星期六(代码中通过偏移量
代码
#include<iostream> using namespace std; int Month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; //平年月 int Lmonth[13]={0,31,29,31,30,31,30,31,31,30,31,30,31}; //闰年月 enum week{Sun,Mon,Tue,Wed,Thu,Fri,Sat}; //星期 bool leap(int year); //判断year是否为闰年 int ComputeDay(int y,int m); //计算从第1年1月1日到第y年m-1月的总天数+1 (即只包括第m个月的第一天) int main(int i,int j,int* pm) { int test; cin>>test; for(int t=0;t<test;t++) { int ys,ms,ye,me; cin>>ys>>ms>>ye>>me; int luck=0,good=0; int day=ComputeDay(ys,ms); if(((day+5)%7<=Mon) || ((day+5)%7==Sat)) //计算起始ys年ms月1号为星期几,判断是否为good month good++; //1年1月1号是星期六,而原本默认是星期日,因此+5调整 /*计算从ys年ms+1开始 到ye-1年的月份是否为good month*/ for(i=ys;i<ye;i++) { if(leap(i)) pm=Lmonth; else pm=Month; if(i==ys) j=ms; else j=1; for(;j<=12;j++) { day+=*(pm+j); if(i==1752 && j==9) day-=11; //由于day开始时+1缘故,当j时,计算的是第j+1月是否为good month if(((day+5)%7<=Mon) || ((day+5)%7==Sat)) //计算j+1月1号为星期几,判断是否为good month { good++; luck++; //当j+1月为good month,j月必为luck month } } } /*计算第ye年的good month*/ if(leap(i)) pm=Lmonth; else pm=Month; if(i==ys) //若ye==ys j=ms; else j=1; for(;j<=me;j++) { day+=*(pm+j); if(i==1752 && j==9) day-=11; //由于day开始时+1缘故,当j时,计算的是第j+1月是否为good month if(((day+5)%7<=Mon) || ((day+5)%7==Sat)) //计算j+1月1号为星期几,判断是否为good month { if(j!=me) good++; luck++; //当j+1月为good month,j月必为luck month } } cout<<luck<<' '<<good<<endl; } return 0; } bool leap(int year) //判断year是否为闰年 { if(year<1582) return !(year%4); //当year<1582时,只要能被4整除就是闰年 else { if(year==1700) //当year=1700时,历史原因,无条件为闰年 return true; if((!(year%4)&&(year%100)) || !(year%400)) //当year>=1582时,能被4整除且不被100整除为闰年 return true; //或能被400整除时为闰年 } return false; } int ComputeDay(int y,int m) //计算从第1年1月1日到第y年m-1月的总天数+1 (即只包括第m个月的第一天) { //"+1"是为了使从当月末变为下月初 int i,j,day=1; for(i=1;i<y;i++) if(leap(i)) day+=366; else day+=365; for(j=1;j<m;j++) if(leap(i)) day+=Lmonth[j]; else day+=Month[j]; if(y>1752) day-=11; else if(y==1752 && m>9) day-=11; return day; }
-
- 1
信息
- ID
- 2394
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 7
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者