版权声明:希望能在自己成长的道路上帮到更多的人,欢迎各位评论交流 https://blog.csdn.net/yiqzq/article/details/82392675
原题地址:http://118.190.20.162/view.page?gpid=T70
思路:具体参考博客
然后这里因为是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;
}