標籤:style http color os io for ar line
題目連結:uva 11534 - Say Goodbye to Tic-Tac-Toe
題目大意:給定一個1*n的個子,每次操作可以選中一個未填過的個子畫X或者O,如果該次操作形成了XX或者OO,那麼該次操作者視為失敗,人為先手,對於給定狀態(注意目前狀態也算在步數中),問是否可以戰勝電腦。
解題思路:對於固定長度,兩端的可能有空,X,O,組合情況共有9種,雖然有些情況等價,但是為方便處理,分為9種情況考慮。預先處理出各個長度下9種情況的SG值。然後對於給定狀態,枚舉位置放X和O,判斷新狀態的Nim和。
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 100;int s[maxn+5][9];int SG (int l, int x, int y) { int vis[maxn+5]; memset(vis, 0, sizeof(vis)); for (int i = 1; i <= l; i++) { if ((i != 1 || x != 1) && (i != l || y != 1)) { int X = s[i-1][x*3+1] ^ s[l-i][1*3+y]; vis[X] = 1; } if ((i != 1 || x != 2) && (i != l || y != 2)) { int O = s[i-1][x*3+2] ^ s[l-i][2*3+y]; vis[O] = 1; } } int mv = -1; while (vis[++mv]); return mv;}void init (int n) { memset(s[0], 0, sizeof(s[0])); for (int i = 0; i < 9; i++) s[1][i] = 1; s[1][1*3+2] = s[1][2*3+1] = 0; for (int i = 2; i <= n; i++) { for (int x = 0; x < 3; x++) { for (int y = 0; y < 3; y++) s[i][x*3+y] = SG(i, x, y); } }}char str[maxn+5];bool judge () { int len = strlen(str+1); int l = 0, r = 0, cnt = 0, ans = 0, k = 0; for (int i = 1; i <= len; i++) { if (str[i] == ‘.‘) k++; else { r = (str[i] == ‘X‘ ? 1 : 2); ans ^= s[k][l*3+r]; cnt++; l = r; k = 0; } } ans ^= s[k][l*3]; if (cnt&1) ans = (ans == 0 ? 1 : 0); return ans;}int main () { init(maxn); int cas; scanf("%d", &cas); while (cas--) { scanf("%s", str+1); printf("%s\n", judge() ? "Possible." : "Impossible."); } return 0;}