原题传送门
dp
表示
是否必胜
判断一下日期合理性就好了
Code:
#include <bits/stdc++.h>
#define maxn 2020
using namespace std;
int dp[maxn][20][40], year, month, date;
bool check(int i, int j, int k){
if (i > 2006 || j > 12 || k > 31 || j < 1 || k < 1) return 0;
if (i >= 2006 && j >= 11 && k >= 4) return 0;
if (j == 1 || j == 3 || j == 5 || j == 7 || j == 8 || j == 10 || j == 12) return k <= 31;
if (j == 4 || j == 6 || j == 9 || j == 11) return k <= 30;
if (i % 400 == 0 || i % 4 == 0 && i % 100 != 0) return k <= 29; else return k <= 28;
}
int main(){
// freopen("calendar.in", "r", stdin);
// freopen("calendar.out", "w", stdout);
// printf("%d\n", check(1904, 4, 31));
dp[2006][11][3] = 1;
for (int i = 2006; i >= 1900; --i)
for (int j = 12; j; --j)
for (int k = 31; k; --k)
if (check(i, j, k)){
int nxti = i, nxtj = j + 1, nxtk = k;
if (nxtj > 12) ++nxti, nxtj = 1;
if (check(nxti, nxtj, nxtk)) dp[i][j][k] |= dp[nxti][nxtj][nxtk] == 0;
// if (i == 2012 && j == 11 && k == 22) printf("%d %d %d\n", nxti, nxtj, nxtk);
nxti = i, nxtj = j, nxtk = k + 1;
if (!check(nxti, nxtj, nxtk)) ++nxtj, nxtk = 1;
if (nxtj > 12) ++nxti, nxtj = 1;
if (check(nxti, nxtj, nxtk)) dp[i][j][k] |= dp[nxti][nxtj][nxtk] == 0;
}
/* int flag = 0;
for (int i = 1900; i <= 1999; ++i)
for (int j = 1; j <= 12; ++j)
for (int k = 1; k <= 31; ++k)
if (check(i, j, k) && !dp[i][j][k]) flag++;
printf("%d\n", flag);*/
int M; scanf("%d", &M);
while (M--){
scanf("%d%d%d", &year, &month, &date);
if (dp[year][month][date]) puts("YES"); else puts("NO");
}
return 0;
}