【BZOJ3759】【博弈论】17.1.24 T1 Hungergame 题解

Hungergame

由于施惠国的统治极其残暴,每年从13个区中每个区中选出2名“贡品”参加饥饿游戏,而参加游戏的人必须在险恶的自然环境中杀死其余的人才能存活。游戏只会有一个人活下来 凯特尼斯•伊夫狄恩和同区的皮塔•麦拉克在历经千难万阻后活了下来,然而残忍的游戏只允许一人存活,正当两人准备同时吃下有毒的果实自杀的时候,统治者被打动了,他说:你们两个人跟我玩一个游戏,你赢了,我就让你们两个都活下来。女主角凯特尼斯•伊夫狄恩接受了挑战。
这个游戏是这样的,有n(n<=20)个箱子,每个箱子里面有ai(ai<=1000000000)个石头(怎么放进去的我就不知道了),两个人轮流进行操作(女主角先手),每一次操作可以将任意个(大于0个)未打开的箱子打开(一开始所有的箱子都是关闭的),或者在已经打开的一个箱子里拿走任意个(大于0个)石头(不能超过这个箱子现有的石头数)。最后谁无法操作谁就输了。
现在给出n,和这n个箱子里的石头数ai,女主角想知道她是否有绝对的把握取得胜利(很明显她的对手“统治者”是绝顶聪明的)。
输入格式(hungergame.in)
第一行有一个正整数T(表示有T组测试数据),对于每组测试数据有两行,第一行为一个正整数n,接下来有 n个数,第 i 个数表示ai.
输出格式(hungergame.out)
有T行:对于每一个测试数据,如果先手可以必胜则输出“Yes”,否则输出“No”(没有引号)。
/然后说明一下,样例我放在题目的文件夹里面了,怕空格来捣乱/
卖萌:
(第一题很萌的啦,题目还是长了一点)
数据范围:
40%的数据:n<=5, T<=5, ai不超过20
100%的数据:n<=20,T<=10,ai不超过1,000,000,000;

直接博弈论,十分简单的一道裸题。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <stack>
#define INF 2100000000
#define ll long long
#define clr(x)  memset(x,0,sizeof(x))

using namespace std;

const int N = 30;
int n,t;
int a[N];

template <class T> inline void read(T &x)
{
    x = 0;
    int flag = 1;
    char ch = (char)getchar();
    while(ch<'0' || ch>'9')
    {
        if(ch=='-') flag = -1;
        ch = (char)getchar();
    }
    while(ch>='0' && ch<='9')
    {
        x = (x<<1) + (x<<3) + ch-'0';
        ch = (char)getchar();
    }
    x *= flag;
}

bool check()
{
    int k(0);
    for(int i = 1<<30; i ; i >>= 1)
    {
        int j;
        for(j = k+1; j <= n; j++) if(a[j]&i) break;
        if(j == n+1) continue;
        k++;
        swap(a[k], a[j]);  
        for(j = 1; j <= n; j++) if(j != k && (a[j]&i)) a[j] ^= a[k];
    }
    return k != n;
}

int main()
{
    freopen("hungergame.in","r",stdin);
    freopen("hungergame.out","w",stdout);
    read(t);
    while(t--)
    {
        read(n);
        for(int i = 1; i <= n; i++) read(a[i]);
        if(check()) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值