1. 程式人生 > 實用技巧 >HDU - 3032 Nim or not Nim? SG函式 打表

HDU - 3032 Nim or not Nim? SG函式 打表

發現很多時候可以從打表中找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] << "\n"; }

發現和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"); } }