1. 程式人生 > >CCF 201803-4 棋局評估 (對抗搜索)

CCF 201803-4 棋局評估 (對抗搜索)

ans clu algo || con mes ccf main using

題意:給一個井字棋的棋盤,對於已經贏的局面,得分是(棋盤上的空格子數+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 }

CCF 201803-4 棋局評估 (對抗搜索)