//poj 1082 Calendar Game (DP/博弈) /* 题解:预处理一下从1900.1.1-2001.11.4之间的每一天开始,Adam先走或后走的胜利者。 dp[year][month][day][1]表示year.month.day这一天Adam先走的胜者,1为Adam胜,0为Adam输。 决策题目中已给出最多两种:加一天或者加一个月,只要有一个决策能够使Adam胜出,Adam在这 一天就可以胜出。 PS: 注意一下闰年和每月天数的判断,不然很容易WA。 */ #include <iostream> #include <algorithm> #include <cmath> using namespace std; const int inf = 1<<28; int n,m; int daynum[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int dp[105][13][32][2]; int isleap(int year) { return year%4==0 || (year%100 && year%400==0); } void init() { memset(dp,-1,sizeof(dp)); int ny,nm,nd; int c=0; for (int i=4;i>=1;i--) { dp[101][11][i][1]=c; dp[101][11][i][0]=(c^=1); } for (int year = 101;year>=0; --year) for (int month = year<101?12:10;month>=1;--month) { if (month==2 && isleap(year)) { for (int i=0;i<=1;i++) if (dp[year][3][29][i^1]==i || dp[year][3][1][i^1]==i) dp[year][2][29][i]=i; else dp[year][2][29][i]=i^1; } for (int day = daynum[month]; day>=1; --day) for (int i=0;i<=1;i++) { if (month==12) ny=year+1,nm=1,nd=day; else ny=year,nm=month+1,nd=day; if (dp[ny][nm][nd][i^1]==i) { dp[year][month][day][i]=i; continue; } if (day==daynum[month]) { if (month==12) ny=year+1,nm=nd=1; else ny=year,nm=month+1,nd=1; } else ny=year,nm=month,nd=day+1; if (dp[ny][nm][nd][i^1]==i) { dp[year][month][day][i]=i; continue; } dp[year][month][day][i]=i^1; } } } int main() { int t;scanf("%d",&t); int year,month,day; init(); while (t--) { scanf("%d%d%d",&year,&month,&day); if (dp[year-1900][month][day][1] == 1 ) printf("YES/n"); else printf("NO/n"); } system("pause"); return 0; }