「The 13th Zhejiang Provincial」 D. The Lucky Week

描述

传送门:我是传送门

Edward, the headmaster of the Marjar University, is very busy every day and always forgets the date.

There was one day Edward suddenly found that if Monday was the 1st, 11th or 21st day of that month, he could remember the date clearly in that week. Therefore, he called such week “The Lucky Week”.

But now Edward only remembers the date of his first Lucky Week because of the age-related memory loss, and he wants to know the date of the N-th Lucky Week. Can you help him?

输入

There are multiple test cases. The first line of input is an integer T indicating the number of test cases. For each test case:

The only line contains four integers Y, M, D and N (1 ≤ N ≤ 109) indicating the date (Y: year, M: month, D: day) of the Monday of the first Lucky Week and the Edward’s query N.

The Monday of the first Lucky Week is between 1st Jan, 1753 and 31st Dec, 9999 (inclusive).

输出

For each case, print the date of the Monday of the N-th Lucky Week.

样例

输入

2
2016 4 11 2
2016 1 11 10

输出

2016 7 11
2017 9 11

思路

  • 蔡勒公式
  • 日期每400年是一次循环

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*
* =================================================================
*
* Filename: zoj3939.cpp
*
* Link: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3939
*
* Version: 1.0
* Created: 2018/10/23 20时21分02秒
* Revision: none
* Compiler: g++
*
* Author: 杜宁元 (https://duny31030.top/), duny31030@126.com
* Organization: QLU_浪在ACM
*
* ================================================================
*/
#include <bits/stdc++.h>
using namespace std;
#define clr(a, x) memset(a, x, sizeof(a))
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define pre(i,a,n) for(int i=n;i>=a;i--)
#define ll long long
#define max3(a,b,c) fmax(a,fmax(b,c))
#define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int Y,M,D,N,t;
int whatday(int d,int m,int y)
{
int ans;
if(m < 3)
m += 12,y--;
ans = (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7;
return ans+1;
}

struct node
{
int y,m,d,id;
node(int y = 0,int m = 0,int d = 0,int id = 0):y(y),m(m),d(d),id(id){}
}p[20100];
int tot = 1;
void init()
{
for(int i = 1753;i <= 1753+399;i++)
{
for(int j = 1;j <= 12;j++)
{
if(whatday(1,j,i) == 1)
{
p[tot] = node(i,j,1,tot);
tot++;
}
if(whatday(11,j,i) == 1)
{
p[tot] = node(i,j,11,tot);
tot++;
}
if(whatday(21,j,i) == 1)
{
p[tot] = node(i,j,21,tot);
tot++;
}
}
}
}


int main()
{
ios
#ifdef ONLINE_JUDGE
#else
freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
#endif
init();
tot--;
scanf("%d",&t);
while(t--)
{
scanf("%d %d %d %d",&Y,&M,&D,&N);
N--;
// 有多少个400年
int ind = N/tot;
int tmp = N%tot;
int flag = 0;
while(Y >= 2153)
{
flag++;
Y -= 400;
}
int yy = 0,mm = 0,dd = 0;
for(int i = 1;i <= tot;i++)
{
if((Y == p[i].y) && (M == p[i].m) && (D == p[i].d))
{
int temp = p[i].id;
temp += tmp;
while(temp > tot)
{
flag++;
temp -= tot;
}
yy = p[temp].y;
mm = p[temp].m;
dd = p[temp].d;
yy += flag*400;
yy += ind*400;
break;
}
}
printf("%d %d %d\n",yy,mm,dd);
}

fclose(stdin);
// fclose(stdout);
return 0;
}