HDU - 3032 Nim or not Nim? SG函式 打表
阿新 • • 發佈:2020-08-19
發現很多時候可以從打表中找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有關。
intget_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"); } }