核心 : 博弈搜索树
双方得分互为相反数
dfs (x,y,player): 玩家player下完(x,y)之后的得分最大值
易错: 先判断输赢,再判断平局
待改进: check() 函数写的还是太臃肿了 233
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 3; 4 int mp[5][5]; 5 int check () { 6 int num=0; 7 for (int i=1;i<=N;i++) 8 for (int j=1;j<=N;j++) 9 if (mp[i][j]==0) num++; 10 for (int i=1;i<=3;i++) { 11 int x=mp[i][1]; 12 if (x==0) continue; 13 for (int j=1;j<=3;j++) { 14 if (mp[i][j]!=x) 15 break; 16 if (j==3) 17 return num+1; 18 } 19 } 20 for (int i=1;i<=3;i++) { 21 int x=mp[1][i]; 22 if (x==0) continue; 23 for (int j=1;j<=3;j++) { 24 if (mp[j][i]!=x) 25 break; 26 if (j==3) 27 return num+1; 28 } 29 } 30 int x=mp[1][1]; 31 if (x&&mp[1][1]==mp[2][2]&&mp[2][2]==mp[3][3]) return num+1; 32 x=mp[2][2]; 33 if (x&&mp[3][1]==mp[2][2]&&mp[2][2]==mp[1][3]) return num+1; 34 if (num==0) return 0; 35 return -1; 36 } 37 int dfs (int x, int y, int player) { 38 mp[x][y] = player; 39 int k = check(); 40 if (k >= 0) { 41 mp[x][y] = 0; 42 return k; 43 } 44 int ans = -100; 45 for (int i = 1; i <= N; i++) 46 for (int j = 1; j <= N; j++) { 47 if (!mp[i][j]) 48 ans = max (ans, dfs(i, j, ( (player - 1) ^ 1) + 1) ); 49 } 50 mp[x][y]=0; 51 return -ans; 52 } 53 int main () 54 { 55 int T; 56 scanf ("%d", &T); 57 while (T--) { 58 for (int i = 1; i <= N; i++) 59 for (int j = 1; j <= N; j++) 60 scanf ("%d", &mp[i][j]); 61 int k=check (); 62 if (k>=0) { 63 printf("%d ",-k); 64 continue; 65 } 66 int ans = -100; 67 for (int i = 1; i <= N; i++) 68 for (int j = 1; j <= N; j++) 69 if (!mp[i][j]) 70 ans = max (dfs(i, j, 1), ans); 71 printf ("%d ", ans); 72 } 73 return 0; 74 }