博弈游戏·Nim游戏·二

题目1 : 博弈游戏·Nim游戏·二

时间限制:10000ms

单点时限:1000ms

内存限制:256MB

描述

Alice和Bob这一次准备玩一个关于硬币的游戏:

N枚硬币排成一列,有的正面朝上,有的背面朝上,从左到右依次编号为1..N。现在两人轮流翻硬币,每次只能将一枚正面朝上的硬币翻过来,并且可以随自己的意愿,在一枚硬币翻转后决定要不要将该硬币左边的任意一枚硬币也翻一次(正面翻到背面或背面翻到正面)。翻最后一枚正面向上的硬币的人获胜。同样的,这次游戏里面Alice仍然先手,两人均采取最优的策略,对于给定的初始局面,Alice会获胜还是Bob会获胜?

提示:Turning Turtles

输入

第1行:1个正整数N,表示硬币数量。1≤N≤10,000

第2行:1个字符串,第i个字符表示编号为i的硬币状态,’H’表示正面朝上,’T’表示背面朝上。

输出

第1行:1个字符串,若Alice能够获胜输出"Alice",否则输出"Bob"

样例输入
8
HHTHTTHT
样例输出
Bob

## 题目解析:

在解答这道题之前,来先看另一道题。有若干堆糖果,Alice 和 Bob 两个人,都可以从一堆糖果中取出至少一个糖,当然也可以把整堆糖一齐取走。取走最后一堆,或最后一颗糖,即对方无法再取糖时,则获胜!问如何解决此问题。

我们假设有三堆糖,分别有12、5、13颗糖。用二进制表示如下:

1 1 0 0

0 1 0 1

1 1 0 1

此时 12 ^ 5 ^ 13 = 0 1 0 0,此时Alice只需要从任意一堆,比如第一堆取走4颗:

1 0 0 0

0 1 0 1

1 1 0 1

那么此时,无论Bob如何从哪堆糖果中取走整堆,或取走若干糖果,其对应的效果即是 该堆的对应的二进制变成一个更小的数字。比如Bob从1 1 0 1取走3颗:

1 0 0 0

0 1 0 1

1 0 1 0

那么Alice只需要从0 1 0 1也取走3颗,

1 0 0 0

0 0 1 0

1 0 1 0

即可使得三堆数字的 XOR 结果还为0,按照这种策略下去,Alice一定可以赢。因此,先行者只需要将每堆的数字 XOR 之后,得到一个结果,如果不为0,那么先行者一定有办法使得改变某一堆的大小,使得之后的所有堆的XOR值为0,那么先行者就赢。

那么针对本文上面提出的题目,如何转化该刚刚所叙述的题目呢?

比如本文的输入

HHTHTTHT

比如对于第7个H,翻转该H时,可以有三种选择:

1,直接只翻转第7个H,不碰其他的H或T

2,翻转第7个H,将其他更低位的某个H变成T

3,翻转第7个H,将其他更低位的某个T变成H

其实可以归为如下操作:

将第7个H,转变成第0个H(即对应上述操作1);

转变成第1个H,并且该H与原先第1位上的H相互抵消,变成T(对应上面操作2);

转变成第2个H,并且该H与原先第2位的H相互抵消,变成T(对应上面操作2);

转变为第3个H,并且该H与原先第3位的T相互结合,变成H(对应上面操作3)

... 依次类推

其实这就对应着刚刚叙述的糖果问题。每个H可以转变为低位的H,即一堆糖果可以取走一部分)。相同位的H可以相互抵消(即两堆一样的糖果,其XOR为0,可以直接抵消,无视)。

因此本题目就与糖果问题一一对应了。一下是代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>

using namespace std;

class Solution {
public:
    void solve() {
        int n, result = 0;
        cin >> n;
        getchar();
        for (int i = 0; i < n; i++) {
            char c = getchar();
            if (c == 'H') {
                result ^= (i+1);
            }
        }
        if (result == 0) printf("Bob\n");
        else printf("Alice\n");
    }
};  

int main() {
    Solution solution;
    solution.solve();
    return 0;
} 
时间: 2024-11-06 21:51:05

博弈游戏·Nim游戏·二的相关文章

hiho一下 第四十五周 博弈游戏&#183;Nim游戏&#183;二 [ 博弈 ]

传送门 题目1 : 博弈游戏·Nim游戏·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Alice和Bob这一次准备玩一个关于硬币的游戏:N枚硬币排成一列,有的正面朝上,有的背面朝上,从左到右依次编号为1..N.现在两人轮流翻硬币,每次只能将一枚正面朝上的硬币翻过来,并且可以随自己的意愿,在一枚硬币翻转后决定要不要将该硬币左边的任意一枚硬币也翻一次(正面翻到背面或背面翻到正面).翻最后一枚正面向上的硬币的人获胜.同样的,这次游戏里面Alice仍然先手,两人均采

hihoCoder#: 博弈游戏&#183;Nim游戏

[题目链接]:click here~~ [题目大意]: #1163 : 博弈游戏·Nim游戏 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 今天我们要认识一对新朋友,Alice与Bob. Alice与Bob总是在进行各种各样的比试,今天他们在玩一个取石子的游戏. 在这个游戏中,Alice和Bob放置了N堆不同的石子,编号1..N,第i堆中有A[i]个石子. 每一次行动,Alice和Bob可以选择从一堆石子中取出任意数量的石子.至少取1颗,至多取出这一堆剩下的所有石

hiho一下 第四十四周 题目1 : 博弈游戏&#183;Nim游戏

题目1 : 博弈游戏·Nim游戏 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 今天我们要认识一对新朋友,Alice与Bob. Alice与Bob总是在进行各种各样的比试,今天他们在玩一个取石子的游戏. 在这个游戏中,Alice和Bob放置了N堆不同的石子,编号1..N,第i堆中有A[i]个石子. 每一次行动,Alice和Bob可以选择从一堆石子中取出任意数量的石子.至少取1颗,至多取出这一堆剩下的所有石子. Alice和Bob轮流行动,取走最后一个石子的人获得胜

[博弈]受限Nim游戏

题目大意:有N(1<=N<=100)堆石子,每堆个数给定A1..AN(1<=Ai<=2,147,483,647),现有甲乙两人轮流取石子,由甲开始,每次选一堆,取走一定数目石子,1到Ai的一半取下整,如Ai=5时,可取1或2,Ai=6时,可取1或2或3,但Ai=1不能取.不能取者负,求甲是否获胜.假定每人都采取最优策略. 这是我第一道用sg来做的题目,先贴一个链接,此人对sg的介绍非常好,至少我一遍看懂了,非常感谢.http://blog.163.com/[email protec

hihoCoder - #1173 : 博弈游戏&#183;Nim游戏&#183;三

#1173 : 博弈游戏·Nim游戏·三 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在这一次游戏中Alice和Bob决定在原来的Nim游戏上增加一条规则:每一次行动时,不仅可以选择一堆取走任意数量的石子(至少取1颗,至多取出这一堆剩下的所有石子),还可以选择将一堆石子分成两堆石子,但并不取走石子.比如说有一堆石子为k个,当Alice或者Bob行动时,可以将这一堆石子分成两堆,分别为x,y.满足x+y=k,x,y>0.那么增加了这一条规则后,在Alice总先手的

杭电acm 2176 取(m堆)石子游戏 (Nim游戏)

取(m堆)石子游戏                                 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)                                                     Total Submission(s): 4524    Accepted Submission(s): 2715 Problem Descri

hiho一下 第四十五周 博弈游戏&#183;Nim游戏&#183;二(转成NIm)

Alice和Bob这一次准备玩一个关于硬币的游戏:N枚硬币排成一列,有的正面朝上,有的背面朝上,从左到右依次编号为1..N.现在两人轮流翻硬币,每次只能将一枚正面朝上的硬币翻过来,并且可以随自己的意愿,在一枚硬币翻转后决定要不要将该硬币左边的任意一枚硬币也翻一次(正面翻到背面或背面翻到正面).翻最后一枚正面向上的硬币的人获胜.同样的,这次游戏里面Alice仍然先手,两人均采取最优的策略,对于给定的初始局面,Alice会获胜还是Bob会获胜? 题意:要使得所有硬币背面向上.每次只能反转一个正面向上

#1163 : 博弈游戏&#183;Nim游戏

题目来自于hihocoder':http://hihocoder.com/problemset/problem/1163?sid=423214 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 今天我们要认识一对新朋友,Alice与Bob. Alice与Bob总是在进行各种各样的比试,今天他们在玩一个取石子的游戏. 在这个游戏中,Alice和Bob放置了N堆不同的石子,编号1..N,第i堆中有A[i]个石子. 每一次行动,Alice和Bob可以选择从一堆石子中取出任意

hihoCoder hiho一下 第四十六周 博弈游戏&#183;Nim游戏&#183;三( sg函数 )

题意:给出几堆石子数量,每次可以取走一堆中任意数量的石头,也可以将一堆分成两堆,而不取.最后取走者胜. 思路:先规矩地计算出sg值,再对每个数量查SG值就可以了.最后求异或和. 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=105, limit=20004; 4 int a[N],n,sg[limit]={0,1,2}; 5 bool B[limit]; 6 int main() 7 { 8 //freopen(