原题 http://acm.zju.edu.cn/onlinejudge/showContestProblem.do?problemId=5699
蔡勒公式,能根据年月日推出礼拜几,
闰年100年不闰400年再闰,不难得出周期是400,能算出400年的n是2058,然后顺推就可以了
注意2016 4 11 2058(一个周期)的答案不是2416 4 11 而是2416 3 21
2016 4 11 1的答案是2016 4 11
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int dd(int d, int m, int y)
{
int ans;
if (m == 1 || m == 2)
{
m += 12;
y--;
}
if ((y < 1752) || (y == 1572 && m < 9) || (y == 1752 && m == 9 && d < 3))
ans = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 + 5) % 7;
else ans = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7;
return ans + 1;
}
int main()
{
//freopen("output.txt", "w", stdout);
//freopen("input.txt", "r", stdin);
int n;
int flag;
scanf("%d", &n);
while (n--)
{
int year, month, day, t;
flag = 0;
scanf("%d%d%d%d", &year, &month, &day, &t);
t--;
year += 400 * (t / 2058);
t %= 2058;
if (t == 0)
{
printf("%d %d %d\n", year, month, day);
continue;
}
for (int i = day + 10; i <= 21; i += 10)
{
if (dd(i, month, year) == 1)
{
t--;
if (t == 0)
{
flag = 1;
printf("%d %d %d\n", year, month, i);
break;
}
}
}
if (flag) continue;
for (int i = month+1; i <= 12; i++)
{
for (int j = 1; j <= 21; j += 10)
{
if (dd(j, i, year) == 1)
{
t--;
if (t == 0)
{
flag = 1;
printf("%d %d %d\n", year, i, j);
break;
}
}
}
if (flag) break;
}
if (flag) continue;
for (int i = year + 1;; i++)
{
for (int j = 1; j <= 12; j++)
{
for (int k = 1; k <= 21; k += 10)
{
if (dd(k, j, i) == 1)
{
t--;
if (t == 0)
{
flag = 1;
printf("%d %d %d\n", i, j, k);
break;
}
}
}
if (flag) break;
}
if (flag) break;
}
if (flag) continue;
}
return 0;
}