hihoCoder - #1173 : 博弈游戏·Nim游戏·三
#1173 : 博弈游戏·Nim游戏·三
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
在这一次游戏中Alice和Bob决定在原来的Nim游戏上增加一条规则:每一次行动时,不仅可以选择一堆取走任意数量的石子(至少取1颗,至多取出这一堆剩下的所有石子),还可以选择将一堆石子分成两堆石子,但并不取走石子。比如说有一堆石子为k个,当Alice或者Bob行动时,可以将这一堆石子分成两堆,分别为x,y。满足x+y=k,x,y>0。那么增加了这一条规则后,在Alice总先手的情况下,请你根据石子堆的情况判断是Alice会获胜还是Bob会获胜?
输入
第1行:1个整数N。表示石子堆数。1≤N≤100
第2行:N个整数,第i个整数表示第i堆石子的个数A[i],1≤A[i]≤20000
输出
第1行:1个字符串,若Alice能够获胜输出"Alice",否则输出"Bob"
- 样例输入
-
3 1 2 4
- 样例输出
-
Bob
打表找下规律,打完表很好做。#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int g[1010]; void init() { memset(g, -1, sizeof(g)); } int getSG(int x) { if(g[x] != -1) return g[x]; if(x == 0) return 0; if(x == 1) return 1; if(x == 2) return 2; int vis[1010]; memset(vis, 0, sizeof(vis)); //printf("check %d\n", x); int tot = 0; for(int i = 1; i < x; i++) { int t = 0; //printf("check %d\n", i); /*g[i] = getSG(i); g[x-i] = getSG(x-i);*/ int a = getSG(i), b = getSG(x - i); t ^= a; t ^= b; //if(x == 3) printf("check %d %d %d\n", t, i, x - i); vis[a] = vis[b] = 1; vis[t] = 1; } vis[tot] = 1; //for(int i = 0; i < x; i++) vis[i] = 1; //vis[x] = 1; for(int i = 0; ; i++) if(!vis[i]) return i; } int main() { int n; init(); //printf("%d ", getSG(3)); for(int i = 1; i <= 100; i++) { g[i] = getSG(i); printf("%d %d %d\n", i, i % 4, g[i]); } //printf("%d\n", 1 ^ 2 ^ 1 ^ 2); }
#include<cstdio> using namespace std; int getSG(int n) { if(n == 0) return 0; if(n % 4 == 0) return n - 1; else if(n % 4 == 3) return n + 1; else return n; } int main() { int n; while(~scanf("%d", &n)) { int flag = 0; for(int i = 1; i <= n; i++) { int tmp; scanf("%d", &tmp); flag ^= getSG(tmp); } if(flag) puts("Alice"); else puts("Bob"); } }