两个核武器科学家Patrick和Roland,在研究核武器时突然觉得无聊,玩起了游戏,游戏当然也是跟核武器有关,游戏一开始在桌子上放了一些核材料,两个人轮流玩,Patrick先玩。游戏规则是每次玩家可以从这些核材料里选一些材料放到反应堆去,当然结果就是化为乌有,由于游戏太危险,所以只有A,B,C,D四种材料,而且允许的反应只有以下5种:
1.AABDD
2.ABCD
3.CCD
4.BBB
5.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
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; int a[5][4]={{2,1,0,2},{1,1,1,1},{0,0,2,1},{0,3,0,0},{1,0,0,1}}; struct node { int i,j,k,t; }; bool win[60][60][60][60]; bool vis[60][60][60][60]; void solve(struct node p) { win[0][0][0][0]=false; for (int i=0;i<=p.i;i++) for (int j=0;j<=p.j;j++) for (int k=0;k<=p.k;k++) for (int t=0;t<=p.t;t++) { if (vis[i][j][k][t]) continue;//记忆化搜索 win[i][j][k][t]=false; for (int l=0;l<5;l++) { win[i][j][k][t] |=((a[l][0] <= i && a[l][1] <= j && a[l][2] <= k && a[l][3] <= t) //必胜与必败的判断点 && !win[i-a[l][0]][j-a[l][1]][k-a[l][2]][t-a[l][3]]); vis[i][j][k][t]=1; if (win[i][j][k][t]) break;//一旦有必胜策略,立即跳出,两位科学家都是绝顶聪明的 } } if (win[p.i][p.j][p.k][p.t]) printf("Patrick\n"); else printf("Roland\n"); } int main() { int t; cin>>t; struct node p; memset(vis,0,sizeof(vis)); memset(win,0,sizeof(win)); vis[0][0][0][0]=1; while (t--) { scanf("%d%d%d%d",&p.i,&p.j,&p.k,&p.t); solve(p); } return 0; }