山东省第八届ACM省赛A题

本文介绍了一个基于石头堆的博弈游戏,并详细解析了游戏规则与获胜策略。通过对不同情况的分析,总结出了当堆数为2时遵循威佐夫博弈规则,大于2时则适用Nim博弈策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值