您的位置:首页 > 其它

山东省第八届ACM省赛A题

2017-07-24 19:03 369 查看
Problem Description

Sherlock and Watson are playing the following modified version of Nim game:

There are n piles of stones denoted as ,,…,, and n is a prime number;

Sherlock always plays first, and Watson and he move in alternating turns. During each turn, the current player must perform either of the following two kinds of moves:

Choose one pile and remove k(k >0) stones from it;

Remove k stones from all piles, where 1≤k≤the size of the smallest pile. This move becomes unavailable if any pile is empty.

Each player moves optimally, meaning they will not make a move that causes them to lose if there are still any better or winning moves.

Giving the initial situation of each game, you are required to figure out who will be the winner

Input

The first contains an integer, g, denoting the number of games. The 2×g subsequent lines describe each game over two lines:

1. The first line contains a prime integer, n, denoting the number of piles.

2. The second line contains n space-separated integers describing the respective values of ,,…,.

1≤g≤15

2≤n≤30, where n is a prime.

1≤pilesi≤ where 0≤i≤n−1

Output

For each game, print the name of the winner on a new line (i.e., either “Sherlock” or “Watson”)

Example Input

2

3

2 3 2

2

2 1

Example Output

Sherlock

Watson

题意:

题目的意思是说有两个人进行博弈,现有两种操作,一种是全部堆取k个,但是k不可超过最小堆中的石子个

数,另一种是可以从任意一堆中取任意个数的石子,题目保证输入的堆数是素数。先拿走最后一颗石子的人

赢,每次都是Sherlock先拿。最后输出获胜玩家的名字。

思路:

1.当n=2时,可以看出是一个简单的威佐夫博弈题目。

威佐夫博弈的结论:

如果 floor ( a[大堆] - b[小堆] ) *( sqrt ( 5.0 ) + 1 ) / 2 == a[小堆]

那么这就是一个奇异局势,谁先拿谁输。

如果等式不成立

那么这就是一个非奇异局势,谁先拿谁赢。

2.当n > 2时,可以发现去掉从所有堆中取k个操作就是一个Nim。

而进行这个取k个操作会产生什么影响呢,举个例子,(大佬的解释)

有3堆石子,分别是15,6,9 然后转换为二进制形式

1  1  1  1
0  1  1  0
1  0  0  1


此时为P态,进行普通Nim操作肯定会破会P态转移到N态,所以此时不会选取这种操作,那么只能尝试对每

堆进行取任意满足条件的k个石子,发现不管怎么取完之后P态也必定会被破坏。原因是,假如对每堆取K个

它们二进制最小的位代表的个数个,则取完之后此位的二进制值都会被取反,所以破坏了P态,而且题目的要

求是素数个堆(除2外都是奇数),对其他满足条件的二进制位进行取也是如此。所以当>2堆时,对P态进行

取同k个操作只会破坏P态,而不会得到想要的P态——>P态,而当为N态时,只需进行普通的Nim操作就可

使N态转化为P态,故加入同取k个操作之后也是满足普通Nim堆的。

所以当n>2时,可以直接当作Nim博弈来做了。

Nim博弈的结论:

如果a[ 1 ] ^ a[ 2 ] ^ a[ 3 ] …… ==0 PS:“^”是异或的符号

那么此时处于P态,即谁先拿谁输。

如果等式不成立

那么此时处于N态,即谁先拿谁赢。

AC代码

#include<cstdio>
#include<cmath>
using namespace std;
int main()
{
int t;
int a[30+5];
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
if(n==2)
{
if(a[1]>a[2])
{
int cc;
cc=a[1];
a[1]=a[2];
a[2]=cc;
}
int k=a[2]-a[1];
int ff=floor(k*(sqrt(5.0)+1)/2);
if(ff==a[1])
{
printf("Watson\n");
}
else
{
printf("Sherlock\n");
}
}
else
{
int tt=a[1];
for(int i=2;i<=n;i++)
{
tt=tt^a[i];
}
if(tt==0)
{
printf("Watson\n");
}
else
{
printf("Sherlock\n");
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm 博弈