Nim or not Nim? - hdu3032

题意:

两人博弈,N堆石子,可以选择移走某一堆的任意数量的石子,也可以选择将这一堆分成任意两堆东西。

思路:和nim游戏差不多,只是多了一个分成两堆的操作,分成两堆也就是计算两个子堆的异或,然后sg函数打表找规律,sg[0]=0,sg[1]=1,2可以变成1+1,1,0,sg[2]=2.....

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4 + 10;
int sg[maxn], vis[maxn];
void init() {
    int i, j, k;
    sg[0] = 0, sg[1] = 1;
    for(i = 2; i <= 1000; i++) {
        memset(vis, 0, sizeof(vis));
        for(j = 1; j < i; j++)
            vis[sg[j]^sg[i - j]] = 1; //拆分
        for(j = 0; j < i; j++)
            vis[sg[j]] = 1;       //取石子
        for(j = 0;; j++)
            if(!vis[j])
                break;
        sg[i] = j;
    }
    for(i = 1; i <= 100; i++)
        cout << sg[i] << endl;
}
int main() {
    init();
}

然后打表发现如果x%4==0则sg[x]=x-1;

若x%4==1||x%4==2,sg[x]=x;

若x%4==3 ,sg[]=x+1;

然后结论出来了.

#include<bits/stdc++.h>
using namespace std;
#define ll long long;
const int N = 1e6 + 10;
int t, n;
int main() {
    cin >> t;
    while(t--) {
        cin >> n;
        int ans = 0;
        for(int j, i = 0; i < n; i++) {
            cin >> j;
            if(j % 4 == 0)
                ans ^= (j - 1);
            else if(j % 4 == 3)
                ans ^= (j + 1);
            else
                ans ^= j;
        }
        if(ans)
            printf("Alice\n");
        else
            printf("Bob\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Endeavor_G/article/details/89740141
Nim