HDU5795 博弈

来源:互联网 发布:新人如何把淘宝做起来 编辑:程序博客网 时间:2024/05/21 09:38

多校的题目

题意,nim游戏,n堆石子,可在一堆中取任意个,也可把一堆分为三堆,最后取完的胜

思路:打表找规律。。x=8k+7时,sg[x]=x+1,x=8k+8时,sg[x]=x-1,其余情况,sg[x]=x。

打表代码:

#include<string>#include<cstring>#include<sstream>#include<iostream>#include<cmath>#include<queue>#include<map>#include<set>using namespace std;int main(){    char str[100];    int sg[10000],MAX;    int vis[10000];    memset(vis,0,sizeof(vis));    memset(sg,0,sizeof(sg));    set<int> s;    sg[0]=0;    for(int i=1;i<100;i++){        s.clear();        for(int j=0;j<i;j++){            s.insert(sg[j]);        }        for(int a=i-2;a>0;a--){            for(int b=a-1;b>0;b--){                for(int c=a-1;c>0;c--){                    if(a+b+c==i){                        s.insert(sg[a]^sg[b]^sg[c]);                    }                }            }        }        int res=0;        while(s.count(res)) res++;        sg[i]=res;        printf("sg[%d]=%d\n",i,sg[i]);    }}

由打表结果得:

AC代码:#include<bits/stdc++.h>using namespace std;int SG(int x){    if(x%8==0)return x-1;    if(x%8==7)return x+1;    return x;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        int n;        scanf("%d",&n);        int ans=0;        int a=0;        for(int i=0;i<n;i++)        {            scanf("%d",&a);            ans ^= SG(a);        }        if(!ans)puts("Second player wins.");        else puts("First player wins.");    }    return 0;}
0 0