2017山东省赛A题(SDUT3893威佐夫博弈+尼姆博奕)

来源:互联网 发布:稀疏编码算法 详解 编辑:程序博客网 时间:2024/05/19 23:14

题意:
G组数据(g<15)
每组数据有n堆石子(n是质数)
接下来是n堆石子数(1≤pilesi≤10^5)
取法:选择一堆取k个,每堆石子取k个

n==2是
是威佐夫博弈
威佐夫博弈
n>2时,第一种取法是典型的nim博弈,而第二种会产生什么影响呢
举个例子:
有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外都是奇数),对其他满足条件的二进制位进行取也是如此。所以当n>2时,对P态进行取同k个操作只会破坏P态,而不会得到想要的P态->P态,而当为N态时,只需进行普通的Nim操作就可使N态转化为P态,故加入同取k个操作之后也是满足普通Nim堆的。
所以当n>2时,同时取k个石子对nim没有影响,即可以把这个游戏看作尼姆游戏.
code:

//威佐夫博弈+尼姆博奕#include<cstdio>#include<math.h>int main(){    int kase;    scanf("%d",&kase);    while(kase--)    {        int n;        scanf("%d",&n);        if(n==2)        {            int a,b,c;            scanf("%d%d",&a,&b);            if(a>b)            {                c=a;                a=b;                b=c;            }            c=b-a;            int w=(int )(((sqrt(5.0)+1.0)/2.0)*c);            if(w==a)                printf("Watson\n");            else                printf("Sherlock\n");        }        else{            int res=0;            for(int i=0;i<n;i++)            {                int a;                scanf("%d",&a);                res^=a;            }            if(res==0)                printf("Watson\n");            else                printf("Sherlock\n");        }    }    return 0;}
原创粉丝点击