HDU5795 博弈

多校的題目

題意,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;
}
發佈了68 篇原創文章 · 獲贊 23 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章