洛谷P1512 伊甸园日历游戏

题目描述

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先操作,问他有没有必胜策略?

输入输出格式

输入格式:

一个测试点。多组数据。

第一行为数据组数。

接下来一行X Y Z表示X年Y月Z日

输出格式:

输出“YES”or“NO”表示亚当是否有必胜策略。

输入输出样例

输入样例#1: 
3
2001 11 3
2001 11 2
2001 10 3
输出样例#1: 
YES
NO
NO

说明

建议先把所有情况都算出来^_^

本来以为是模拟题,然而想了半天没思路。。。

看了题解,终于明白是记忆化搜索。。。

附代码:

#include
#include
#include
#include
using namespace std;
const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int t,y,m,d,f[2010][15][35];
bool rn(int x){
     if((x%4==0&&x%100!=0)||x%400==0)
     return true;
     return false;
}
void work(){
     int a=2001,b=11,c=4;
     f[2001][11][4]=0;
     while(!(a==1900&&b==1&&c==1)){
                                   if(!f[a][b][c]){
                                                   if(b==1&&c==1)f[a-1][12][31]=1;
                                                   else if(c==1){
                                                        if(rn(a)&&b==3)f[a][b-1][day[b-1]+1]=1;
                                                        else f[a][b-1][day[b-1]]=1;
                                                        }
                                                   else f[a][b][c-1]=1;
                                                   if(b==1)f[a-1][12][c]=1;
                                                   else if(rn(a)&&b==3&&c<=day[b-1]+1)f[a][b-1][c]=1;
                                                   else if(c<=day[b-1])f[a][b-1][c]=1;
                                                   }
                                   if(b==1&&c==1){a--;b=12;c=31;}
                                   else if(c==1){
                                        if(rn(a)&&b==3&&c==1){b=2;c=29;}
                                        else{b--;c=day[b];}
                                        }
                                   else c--;
                                   }
}
int main(){
    work();
    scanf("%d",&t);
    while(t--){
               scanf("%d%d%d",&y,&m,&d);
               if(f[y][m][d])printf("YES\n");
               else printf("NO\n");
               }
    return 0;
}

你可能感兴趣的:(数论,模拟)