QUST第七届省选-游戏

题目描述

两个核武器科学家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


样例输出

Roland
Patrick
Roland
Roland
Roland
Patrick

提示



分析:这是一个博弈的问题,可以用对抗搜索来做,A 与 B博弈,若A必胜则B必败,两人的必胜态与必败态是对立的,对抗搜索可以解决,但注意记忆化搜索,否则会超时
但其实我的方法效率也不是非常高(跪大神)

#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;
}






  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值