LightOj1296Again Stone Game(手推SG函式)

Ada Chambers發表於2020-10-03

題意

把Nimm遊戲的任意改成每次取的數量不超過當前的一半。

題解

暴力遞推SG函式的話複雜度是 O ( n m 2 ) O(nm^2) O(nm2),n是堆數,m是堆的大小。稍微思考(實際上我是打表找規律發現的)可以發現,狀態k和狀態2k+1擁有相同的SG值,而偶數的SG值是它除以2。所以對於一個奇數,把他減1在除以2,一直到變為偶數,SG值就是這個偶數除以2。注意開始的幾項不太一樣,要特判。

AC程式碼

#include <bits/stdc++.h>

using namespace std;
int n;
int main()
{
    int t;scanf("%d",&t);
    for(int z=1;z<=t;z++){
        scanf("%d",&n);
        int ans=0;
        for(int i=1;i<=n;i++){
            int x;scanf("%d",&x);
            int res=0;
            while(x%2==1){
                x=(x-1)/2;
                if(x==1){
                    res=1;break;
                }
            }
            if(x==2){
                res=0;
            }
            else res=x/2;
            ans^=res;
        }
        printf("Case %d: ",z);
        if(ans!=0){
            printf("Alice\n");
        }
        else printf("Bob\n");
    }
    return 0;
}

相關文章