题意:从一个日期开始,两个人轮流选择日期,可以选择上一个人所选日期的后一天,也可以选择下一个月的这天。
思路:从目标日期开始求出所有的sg值。判断sg值是否为0
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <string>
#define LL long long
#define DB double
#define SF scanf
#define PF printf
#define N 2009
#define bug cout<<"bug"<<endl;
using namespace std;
int dp[N][14][33];
bool run(int y)
{
if(y%400==0) return 1;
if(y%100==0) return 0;
return (y%4)==0;
}
bool ok(int y,int m,int d)
{
if(m==2)
{
if(run(y))
{
return d<=29;
}else
{
return d<=28;
}
}
if(m==1||m==3||m==5||m==7||m==8||m==10||m==12)
{
return d<=31;
}else
{
return d<=30;
}
}
int fin1(int y,int m,int d)
{
if(m<12)
return dp[y][m+1][d];
else
return dp[y+1][1][d];
}
int fin2(int y,int m,int d)
{
if(m==12&&d==31)
return dp[y+1][1][1];
if(dp[y][m][d+1]==-1)
return dp[y][m+1][1];
return dp[y][m][d+1];
}
void init()
{
memset(dp,-1,sizeof(dp));
for(int y=2001;y>=1900;y--)
for(int m=12;m>0;m--)
for(int d=31;d>0;d--)
{
if(!ok(y,m,d)) continue;
int t1 = fin1(y,m,d);
int t2 = fin2(y,m,d);
if(t1!=0&&t2!=0) dp[y][m][d] = 0;
else if(t1!=1&&t2!=1) dp[y][m][d] = 1;
else if(t1!=2&&t2!=2) dp[y][m][d] = 2;
else dp[y][m][d] = 3;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
init();
int cas,y,m,d;SF("%d",&cas);
while(cas--)
{
SF("%d%d%d",&y,&m,&d);
PF("%s",dp[y][m][d]!=0?"YES\n":"NO\n");
}
return 0;
}