sdut 3893 Return of the Nim(matrix nim)

来源:互联网 发布:python遍历一个字符串 编辑:程序博客网 时间:2024/05/29 08:32

题意:

n堆石子,n为质数,(2<=n<=30)a,b两人轮流取石子,有两种取法,一种是从每堆石子中去k个石子,第二种是从每堆石子中去k个石子,k必需小于n堆中最小的个数。


解题思路:

这是个1*n的matrix nim,貌似只能解n为奇数的情况和n=2的情况,n=2的时候就是威瑟夫博弈。

n不是2的情况的时候,考虑这个题如果没有第二种操作,就是nim博弈,我们可以考虑去每堆石子去k个石子是否会影响当前的np状态。对于n状态,我们不需要用第二种操作,用第一种操作就肯定可以找到一个继承状态是必败的,即异或为0.而对于一个p状态,即当前异或和为0的状态,我们考虑k转换为二进制后最小的那位1在x位,每堆减去一个k,那么每堆数x位的值都肯定取反了,由于有奇数堆,所以这一位上的异或和肯定发生了改变,也就是说这一位肯定由0变成了1,所以即使考虑了第二种操作p状态的所有后继状态仍然是非零的,所以这种情况仍然符合nim博弈。


代码:

#include <bits/stdc++.h>using namespace std;int main(){    int t;    cin>>t;    while(t--)    {        int n;        scanf("%d", &n);        if(n==2)        {            int x, y;            scanf("%d%d", &x, &y);            if(x<y)swap(x,y);            if(y==int((x-y)*1.0*(1+sqrt(5.0))/2) )            {                printf("Watson\n");            }            else             {                printf("Sherlock\n");            }            continue;        }        int i, j, nim=0;        for(i=0; i<n; i++)        {            scanf("%d", &j);            nim^=j;        }        if(nim)printf("Sherlock\n");        else printf("Watson\n");    }}


0 0
原创粉丝点击