题目大意
题目很长,但意思很简单。
告诉你如果一个月的最后一个工作日是周五那么这个月就叫做Lucky month
如果一个月的第一工作日是周一就叫做Good month
问从某年某月到某年某月之间有的多少个Lucky month 和 Good month
分析
题目信息
(1)1年1月1日为星期6
(2)润年的判定方法如下:
若year<1582,则year%4==0 为润年,否则为平年
若year>=1582,则year%4==0 && year%100!=0 ||year%400==0 为润年,否则为平年,注意1700规定为润年。
(3)1752年是不寻常的年份,其9月从3号开始到13号结束都没有天数。
然后就一天一天地推
代码
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<map>
#include<algorithm>
#include<set>
using namespace std;
int month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int Ys,Ms,Ye,Me;
bool Is_leapyear(int y)//判断x是否是闰年
{
if(y==1700)return 1;
else if(y>0 && y<1582 )
{
if(y%4==0)return 1;
else return 0;
}
else if(y%4==0 && (y%100!=0 || y%400==0))return 1;
else return 0;
}
int Month(int y,int m)
{
if(Is_leapyear(y) && m==2)return month[m]+1;
else return month[m];
}
void Init()//求公元0年1月1日是星期几 3
{
//2017 2 13 星期1
int y=2017;
int m=2;
int d=13;
int w=1;
while(1)
{
if(y==1752 && m==9 && d==14){d=2;w=(w+5)%7+1;continue;}
if(y==0 && m==1 && d==1)break;
w=(w+5)%7+1;//求这一天的前一天是星期几
if(m==1 && d==1){y--;m=12;d=31;}//年份徐需要改变的情况
else if(d==1){m=(m+10)%12+1;d=Month(y,m);}
else d--;
}
//cout<<w<<endl;
}
void Get(int Y,int M,int &lucky,int &good)//求从1年1月到y年m月之间有多少lucky month 和good month
{
int y,m,d,w;
lucky=0;good=0;
y=0;m=1;d=1;w=4;
while(1)
{
// if(y==2006 && m==9 && d==1)cout<<"2006 9 1: "<<w<<endl;
if(y==1752 && m==9 && d==2){d=14;w=w%7+1;continue;}
if(y==Y && m==M && d==Month(y,m) )break;
w=w%7+1;
if(m==12 && d==31){y++;m=1;d=1;}
else if(d==Month(y,m))
{
d=1;
m=(m)%12+1;
}
else d++;
if(d==1)
{
if(w==6||w==7||w==1)good++;
}
if(Month(y,m)==d)
{
if(w==5||w==6||w==7)lucky++;
}
}
}
void Work()
{
int lucky_s,good_s;
int lucky_e,good_e;
Get(Ys,Ms,lucky_s,good_s);
Get(Ye,Me,lucky_e,good_e);
cout<<lucky_e-lucky_s<<" "<<good_e-good_s<<endl;
}
int main()
{
int T;
scanf("%d",&T);
Init();
while(T--)
{
cin>>Ys>>Ms>>Ye>>Me;
if(Ms==1){Ys--;Ms=12;}
else {Ms=(Ms+10)%12+1;}
Work();
}
return 0;
}
/*
2
1 1
2017 8
1 2
2017 8
*/