题目链接:http://hihocoder.com/problemset/problem/1172
#1172 : 博弈游戏·Nim游戏·二
-
8 HHTHTTHT
样例输出
-
Bob
描述
Alice和Bob这一次准备玩一个关于硬币的游戏:
N枚硬币排成一列,有的正面朝上,有的背面朝上,从左到右依次编号为1..N。现在两人轮流翻硬币,每次只能将一枚正面朝上的硬币翻过来,并且可以随自己的意愿,在一枚硬币翻转后决定要不要将该硬币左边的任意一枚硬币也翻一次(正面翻到背面或背面翻到正面)。翻最后一枚正面向上的硬币的人获胜。同样的,这次游戏里面Alice仍然先手,两人均采取最优的策略,对于给定的初始局面,Alice会获胜还是Bob会获胜?
输入
第1行:1个正整数N,表示硬币数量。1≤N≤10,000
第2行:1个字符串,第i个字符表示编号为i的硬币状态,’H’表示正面朝上,’T’表示背面朝上。
输出
第1行:1个字符串,若Alice能够获胜输出"Alice",否则输出"Bob"
翻硬币问题系列详解:http://blog.youkuaiyun.com/y990041769/article/details/21645153
结论:局面的sg值等于每个正面朝上的棋子单一存在时的sg异或值
解题思路:sg
对于第i个棋子朝上:TTTT.....H
1.将第i个H翻过来,相当于将一堆i个的石子全部去掉。
2.将第i个H翻过来,同时将第j个T翻过来,相当于将一堆i个的石子取掉一部分变成j个的石子堆。
所以sg值为i
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
int sg=0, i, j;
char x;
scanf("\n");
for(i=1; i<=n; i++)
{
scanf("%c", &x);
if(x=='H')sg^=i;
}
if(sg==0)printf("Bob\n");
else printf("Alice\n");
}