HDU_2873
由于每次炸弹爆炸后剩下生成的炸弹都会往角上缩,因此如果把炸弹的状态看成一个节点的话实际上这是一个有向无环图的公平组合游戏,所以可以用SG函数的理论来求解。由于每个炸弹都是独立的,可以把每个炸弹的SG函数值通过记忆化搜索计算出来,然后异或到一起就是整个局面的SG函数值。
#include<stdio.h> #include<string.h> #define MAXN 60 #define MAXD 2510 int N, M, sg[MAXN][MAXN]; char b[MAXN]; void prep() { int i; memset(sg, -1, sizeof(sg)); sg[1][1] = 0; for(i = 2; i <= 50; i ++) sg[1][i] = sg[i][1] = i - 1; } int dfs(int x, int y) { if(sg[x][y] != -1) return sg[x][y]; int i, j, h[MAXD]; memset(h, 0, sizeof(h)); for(i = 1; i < x; i ++) for(j = 1; j < y; j ++) h[dfs(i, y) ^ dfs(x, j)] = 1; for(i = 0; h[i]; i ++); return sg[x][y] = i; } void solve() { int i, j, ans = 0; for(i = 1; i <= N; i ++) { scanf("%s", b + 1); for(j = 1; j <= M; j ++) if(b[j] == '#') ans ^= dfs(i, j); } printf("%s\n", ans ? "John" : "Jack"); } int main() { prep(); while(scanf("%d%d", &N, &M), N) solve(); return 0; }