题目链接:
D - The Lucky Week
题目大意:幸运的星期指,星期一为每个月的1 or 11 or 21号。给出第一个幸运星期的时间,问从当前的日起开始。第n个的日期。
具体思路:我们通过打表可以发现,每隔400年,当前的这一天的星期和400年后的是相同的。所以我们先求出一个400年有多少个幸运的天数(1600-1999),然后判断当前的年份如果以1600年开始的话,往后n个幸运日是多少,然后再做差以原来的起点输出就可以了。
AC代码:
1 #include<bits/stdc++.h>
2 using namespace std;
3 # define ll long long
4 # define inf 0x3f3f3f3f
5 const int maxn = 2e6+100;
6 struct node
7 {
8 ll y,m,d;
9 node() {}
10 node(ll xx,ll yy,ll zz)
11 {
12 y=xx;
13 m=yy;
14 d=zz;
15 }
16 } ;
17 //bool check(ll y,ll m,ll d)
18 //{
19 // ll a;
20 // if(m==1||m==2)
21 // {
22 // m+=12;
23 // y--;
24 // }
25 // if((y<1752)||(y==1752&&m<9)||(y==1752&&m==9&&d<3))
26 // a=(d+2*m+3*(m+1)/5+y+y/4+5)%7;
27 // else
28 // a=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7;
29 // if(a==0)
30 // return true;
31 // return false;
32 //}
33 bool check(int year,int month,int day)
34 {
35 if(month < 3) { year -= 1; month += 12; }
36 int c = int (year / 100), y = year - 100 * c;
37 int w = int ( c / 4) - 2 * c + y + int ( y / 4 ) +(26 * ( month + 1 ) / 10) + day - 1;
38 w = (w % 7 + 7) % 7;
39
40 if (w == 1) return 1;
41 else return 0;
42 }
43 vector<node>q;
44 map<ll,ll>vis;
45 void init(){
46 for(ll i=1600;i<=1600+400-1;i++){
47 for(ll j=1;j<=12;j++){
48 if(check(i,j,1)){
49 q.push_back(node(i,j,1));
50 vis[i*1000+j*100+1]=q.size()-1;
51 }
52 if(check(i,j,11)){
53 q.push_back(node(i,j,11));
54 vis[i*1000+j*100+11]=q.size()-1;
55 }
56 if(check(i,j,21)){
57 q.push_back(node(i,j,21));
58 vis[i*1000+j*100+21]=q.size()-1;
59 }
60 }
61 }
62 }
63 int main()
64 {
65 init();
66 int T;
67 scanf("%lld",&T);
68 while(T--)
69 {
70 ll y,m,d,n;
71 scanf("%lld %lld %lld %lld",&y,&m,&d,&n);
72 ll tmp1,tmp2;
73 tmp1=(y-1600)%400+1600;
74 tmp2=tmp1*1000+m*100+d;
75 int pos=vis[tmp2];
76 int t1=(pos+n-1)%q.size();
77 int t2=(pos+n-1)/q.size();
78 printf("%lld %lld %lld
",y+q[t1].y-q[pos].y+t2*400,q[t1].m,q[t1].d);
79 }
80 return 0;
81 }