伊甸园日历游戏
描述 Description
Adam和Eve玩一个游戏,他们先从1900.1.1到2001.11.4这个日期之间随意抽取一个日期出来。然后他们轮流对这个日期进行操作:
1 : 把日期的天数加1,例如1900.1.1变到1900.1.2
2 : 把月份加1,例如:1900.1.1变到1900.2.1
其中如果天数超过应有天数则日期变更到下个月的第1天。月份超过12则变到下一年的1月。而且进行操作二的时候,如果有这样的日期:1900.1.31,则变成了1900.2.31,这样的操作是非法的,我们不允许这样做。而且所有的操作均要考虑历法和闰年的规定。
谁先将日期变到2001.11.4谁就赢了。
每次游戏都是Adam先操作,问他有没有必胜策略?
输入格式 Input Format
一个测试点。多组数据。
第一行为数据组数。
接下来一行X Y Z表示X年Y月Z日
输出格式 Output Format
输出“YES”or“NO”表示亚当是否有必胜策略。
逆推,DP
#include<iostream> using namespace std; int t,year,month,day; int f[2012][20][40]={0}; int tool[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; void Dp(){ int y=2001,m=11,d=4; f[2001][11][4]=1; while(!(y==1900&&m==1&&d==1)) { int y1=y,m1=m,d1=d; d--; if(d==0) { m--; if(m==0) { m=12; y--; } d=tool[m]; if(((y%4==0&&y%100!=0)||y%400==0)&&m==2) d+=1; } if(f[y1][m1][d1]==1) {f[y][m][d]=2;continue;} y1=y;m1=m;d1=d; m1++; if(m1==13) { y1++; m1=1; } if(f[y1][m1][d1]==1) f[y][m][d]=2; else f[y][m][d]=1; } } int main() { Dp(); cin>>t; while(t>0) { t--; cin>>year>>month>>day; if(f[year][month][day]==2) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }