核心 : 博弈搜索树 

       双方得分互为相反数

   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\n",-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\n", ans);
72   }
73   return 0;
74 }