时间限制: 1000 ms 空间限制: 262144 KB 具体限制
题目描述
两个核武器科学家Patrick和Roland,在研究核武器时突然觉得无聊,玩起了游戏,游戏当然也是跟核武器有关,游戏一开始在桌子上放了一些核材料,两个人轮流玩,Patrick先玩。游戏规则是每次玩家可以从这些核材料里选一些材料放到反应堆去,当然结果就是化为乌有,由于游戏太危险,所以只有A,B,C,D四种材料,而且允许的反应只有以下5种:
-
AABDD
-
ABCD
-
CCD
-
BBB
-
AD
当某个人选不到材料进行反应时就输了,大家要知道两个人都是绝顶聪明的。
输入
第一行输入一个整数N(1<=N<=100),表示游戏次数,接下来N行,每行四个整数,分别表示游戏开始时A,B,C,D四种材料的数量。假设一开始每种材料的数量都在0到60之间。
输出
对于每次游戏输出赢者的名字。
样例输入
6
0 2 0 2
1 3 1 3
1 5 0 3
3 3 3 3
8 8 6 7
8 8 8 8
样例输出
Roland
Patrick
Roland
Roland
Roland
Patrick
思路
看到这道题的时候最初懵了一下,但发现其实就是无限列举,无限递归,把必胜情况翻出来,话不多说,看代码
#include<bits/stdc++.h>
using namespace std;
int f[61][61][61][61],n,u,v,w,x;
int dfs(int a,int b,int c,int d)
{
if(f[a][b][c][d]) return f[a][b][c][d];
if(a>1&&b>0&&d>1)
if(dfs(a-2,b-1,c,d-2)==2) //搜下一种 有第一种便判断第一种
return f[a][b][c][d]=1;
if(a>0&&b>0&&c>0&&d>0)
if(dfs(a-1,b-1,c-1,d-1)==2) //同上
return f[a][b][c][d]=1;
if(c>1&&d>0)
if(dfs(a,b,c-2,d-1)==2) //同上
return f[a][b][c][d]=1;
if(b>2)
if(dfs(a,b-3,c,d)==2)
return f[a][b][c][d]=1; // 同上
if(a>0&&d>0)
if(dfs(a-1,b,c,d-1)==2)
return f[a][b][c][d]=1; //同上
return f[a][b][c][d]=2; //都不行,便这个人输了
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d %d %d %d",&u,&v,&w,&x);
if(dfs(u,v,w,x)==1) puts("Patrick");else puts("Roland");
}
}
程序大概就是这样,如果有不懂的或是能够进行优化的请在评论里提出,大家一起进步!