HDU

发现很多时候可以从打表中找SG函数的规律。

此题如果没有分割这个操作其实就是简单是异或一下就好了(其实就是SG函数)

多的这个操作想到与考虑后继状态 sg(x + y ) 。我们知道sg(x + y ) 可以从 sg(x) ^ sg(y) 求出。于是可以尝试先打表出sg函数。

int vis[105];
int sg[105];

void init() {
    for (int i = 0; i <= 100; i++) {
        memset(vis, 0, sizeof vis);
        for (int j = 1; j <= i; j++) vis[sg[i - j]] = 1;
        for (int j = 1; j < i; j++) vis[sg[j] ^ sg[i - j]] = 1;
        for(int  j = 0;;j++)
            if (!vis[j]) {
                sg[i] = j;
                break;
            }
    }
    for (int i = 0; i <= 100; i++) cout << i << " " << sg[i] << "
";
}

发现和4有关。

int get_sg(int x) {
    if (x % 4 == 0) return x - 1;
    else if (x % 4 == 1 || x % 4 == 2) return x;
    else return x + 1;
}

于是对所有堆sg异或一下就好了。

int main() {
    //init();
    int T = readint();
    while (T--) {
        int n = readint();
        int res = 0;
        for (int i = 0; i < n; i++) {
            int x = readint();
            res ^= get_sg(x);
        }
        if (!res) puts("Bob");
        else puts("Alice");
    }
}
原文地址:https://www.cnblogs.com/hznumqf/p/13532194.html