CCF 201803-4 棋局评估 (对抗搜索)
题意:给一个井字棋的棋盘,对于已经赢的局面,得分是(棋盘上的空格子数+1)*(A为1,B为-1),给出现在的局面求最后的得分
思路:这个叫对抗搜索,每次换一个人搜一下,上次考我还在想下哪里?结果答案是:搜索,随便下
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #define LL long long 6 #define debug(x) cout << "[" << x << "]" << endl 7 using namespace std; 8 9 int a[3][3]; 10 11 bool row(int r, int p){ 12 return a[r][0] == p && a[r][1] == p && a[r][2] == p; 13 } 14 15 bool col(int c, int p){ 16 return a[0][c] == p && a[1][c] == p && a[2][c] == p; 17 } 18 19 int sum(){ 20 int ans = 0; 21 for (int i = 0; i < 3; i++) 22 for (int j = 0; j < 3; j++) 23 if (!a[i][j]) ans++; 24 return ans; 25 } 26 27 int win(int p){ 28 int ans = 1; 29 bool ok = 0; 30 if (row(0, p) || row(1, p) || row(2, p)) ok = 1; 31 if (col(0, p) || col(1, p) || col(2, p)) ok = 1; 32 if (a[0][0] == p && a[1][1] == p && a[2][2] == p) ok = 1; 33 if (a[0][2] == p && a[1][1] == p && a[2][0] == p) ok = 1; 34 if (!ok) return 0; 35 ans += sum(); 36 return p == 1 ? ans : -ans; 37 } 38 39 int dfs(int p){ 40 if (!sum()) return 0; 41 int Max = -10, Min = 10; 42 for (int i = 0; i < 3; i++){ 43 for (int j = 0; j < 3; j++){ 44 if (a[i][j]) continue; 45 a[i][j] = p+1; 46 int w = win(p+1); 47 if (w){ 48 a[i][j] = 0; 49 return w > 0 ? max(Max, w) : min(Min, w); 50 } 51 if (!p) Max = max(Max, dfs(1)); 52 else Min = min(Min, dfs(0)); 53 a[i][j] = 0; 54 } 55 } 56 return p ? Min : Max; 57 } 58 59 int main(){ 60 int t; 61 scanf("%d", &t); 62 while (t--){ 63 for (int i = 0; i < 3; i++) 64 for (int j = 0; j < 3; j++) 65 scanf("%d", &a[i][j]); 66 int x = win(1), y = win(2); 67 if (x) { printf("%d\n", x); continue; } 68 if (y) { printf("%d\n", y); continue; } 69 printf("%d\n", dfs(0)); 70 } 71 return 0; 72 }