Laoj P1356 伊甸园日历游戏
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Laoj P1356 伊甸园日历游戏相关的知识,希望对你有一定的参考价值。
试题描述
|
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”表示亚当是否有必胜策略。
|
输入示例
|
3
2001 11 3 2001 11 2 2001 10 3 |
输出示例
|
YES
NO NO |
试题来源
|
From ZJU
|
【分析】
博弈论+记忆化搜索。
乍一看有点懵,分析一下可以简化,每个状态可以向下分成两个新状态,只要在这其中的一个状态是不合法的,就等于把这个不合法的状态给了对手,那么自己就是必赢的。
这题的数据有点坑,其中有本来就不合法(在2011.11.4之后)的,所以要先判断一下。
【代码】
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int t, a, b, c, x, y, z; 5 int f[2015][15][35]; 6 int m[13]={0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 7 8 int fun(int a) { 9 return (a%400==0 || (a%4==0 && a%100)); 10 } 11 12 bool check(int x, int y, int z) { 13 if (x>2001) 14 return false; 15 if (x==2001 && ((y==11 && z>4)||y==12)) 16 return false; 17 return true; 18 } 19 20 void get1(int &x, int &y, int &z) { 21 int maxx=m[y]; 22 if (y==2) 23 maxx+=fun(x); 24 if (z>maxx) 25 y++, z=1; 26 if (y>12) 27 x++, y=1; 28 return; 29 } 30 31 void get2(int &x, int &y, int &z) { 32 if (y>12) 33 x++, y-=12; 34 int maxx=m[y]; 35 if (y==2) 36 maxx+=fun(x); 37 if (z>maxx) { 38 x=2002; 39 return; 40 } 41 return; 42 } 43 44 int dfs(int a, int b, int c) { 45 if (a==2001 && b==11 && c==4) 46 return f[a][b][c]=0; 47 if (f[a][b][c]!=-1) 48 return f[a][b][c]; 49 if (!check(a, b, c)) 50 return f[a][b][c]=1; 51 x=a, y=b, z=c; 52 z++; get1(x, y, z); 53 if (!dfs(x, y, z)) 54 return f[a][b][c]=1; 55 x=a, y=b, z=c; 56 y++; get2(x, y, z); 57 if (!dfs(x, y, z)) 58 return f[a][b][c]=1; 59 return f[a][b][c]=0; 60 } 61 62 int main() { 63 cin >> t; 64 memset(f, -1, sizeof(f)); 65 for (int i=1;i<=t;++i) { 66 cin >> a >> b >> c; 67 if (!check(a, b, c)) { 68 cout << "NO" << endl; 69 continue; 70 } 71 if (f[a][b][c]==-1) 72 dfs(a, b, c); 73 if (f[a][b][c]) 74 cout << "YES" << endl; 75 else 76 cout << "NO" << endl; 77 } 78 }
以上是关于Laoj P1356 伊甸园日历游戏的主要内容,如果未能解决你的问题,请参考以下文章