1. 程式人生 > >CCF201803-4-棋局評估 (對抗搜尋)

CCF201803-4-棋局評估 (對抗搜尋)

思路:具體參考部落格
然後這裡因為是3*3的格子,所以情況不多,主要是用到了極小值極大值策略,如果資料再大,需要用到a-b剪枝。

具體ac程式碼:

#include <bits/stdc++.h>
#define eps 1e-8
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define lson l,mid,rt<<1
#define rson mid+1,r,(rt<<1)+1
#define CLR(x,y) memset((x),y,sizeof(x))
#define fuck(x) cerr << #x << "=" << x << endl
using namespace std; typedef long long ll; typedef unsigned long long ull; const int seed = 131; const int maxn = 1e5 + 5; const int mod = 1e9 + 7; int t; int a[5][5]; bool okrow(int f, int x) {//表示第f個人,第x行 return a[x][1] == f && a[x][2] == a[x][1] && a[x][1] == a[x][3]; } bool okcol(int
f, int x) { //表示第f個人,第x列 return a[1][x] == f && a[1][x] == a[2][x] && a[2][x] == a[3][x]; } bool okxie(int f) {//判斷井字棋斜著能不能贏 if (a[1][1] == f && a[2][2] == a[1][1] && a[1][1] == a[3][3]) return 1; if (a[3][1] == f && a[2][2] == a[3][1] && a[1
][3] == a[2][2]) return 1; return 0; } int check(int f) {//判斷當前棋盤分數 int ans = 1; for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 3; j++) { if (a[i][j] == 0) ans++; } } if (f == 1) return ans; else return -ans; } bool win(int f) {//判斷f能不能贏 if (okrow(f, 1) || okrow(f, 2) || okrow(f, 3)) return 1; if (okcol(f, 1) || okcol(f, 2) || okcol(f, 3)) return 1; if (okxie(f)) return 1; return 0; } int dfs(int peo) { //1表示alice 2表示bob下棋 if (check(1) == 1) return 0;//如果沒有位置可以填了,那麼就是平局 int MAX = -INF;//初始化最大值 int MIN = INF;//初始化最小值 for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 3; j++) { if (a[i][j]) continue; a[i][j] = peo;//給當前位置賦值 if (win(peo)) {//如果下了這個棋子之後能贏 if (peo == 1) MAX = max(MAX, check(1));//比較 else MIN = min(MIN, check(2)); a[i][j] = 0;//回溯 continue; } //下了棋子之後不能贏,那麼就需要繼續遞迴 if (peo == 1) { MAX = max(MAX, dfs(2)); } else { MIN = min(MIN, dfs(1)); } a[i][j] = 0;//回溯 } } if (peo == 1) return MAX; else return MIN ; } int main() { scanf("%d", &t); while (t--) { for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 3; j++) { scanf("%d", &a[i][j]); } } int x = win(1);//初始棋面Alice能贏 int y = win(2);//初始棋Bob能贏 if (x) printf("%d\n", check(1)); else if (y) printf("%d\n", check(2)); else printf("%d\n", dfs(1)); } return 0; }