分析
棋局评估策略:
- Alice:往大赢
- Bob:往小赢
用dfs,题目规定Alice先下,每次对还未放置的位置(0)放下Alice的棋子$x$,之后dfs到Bob的操作阶段,每次都判断当前局面是否可以结束,如果可以,就返回答案。
C++ 代码
#include<bits/stdc++.h>
using namespace std;
const int INF = 1e8;
int g[3][3];
bool check(int x) //判断当前是否可以结束棋局,x为1表示Alice手结束,2表示Bob手结束
{
if(g[0][0]==x && g[1][1]==x && g[2][2]==x) return true;
if(g[2][0]==x && g[1][1]==x && g[0][2]==x) return true;
for(int i=0;i<3;i++)
{
if(g[i][0]==x && g[i][1]==x && g[i][2]==x) return true;
if(g[0][i]==x && g[1][i]==x && g[2][i]==x) return true;
}
return false;
}
int jdg() //统计当前棋局的空白位置个数
{
int res=0;
for(int i = 0; i < 3; i ++ )
for(int j = 0; j < 3; j ++ )
if(!g[i][j])
res++;
if(check(1)) return res+1; //若是Alice让比赛结束了,就返回正数
if(check(2)) return -(res+1); //若是Bob,返回负数
if(!res) return 0; //平局返回0
return INF; //默认返回INF
}
int dfs(int u) //对棋局进行搜索
{
int t=jdg();
if(t!=INF) return t;
if(!u) //轮到Alice
{
int res=-INF; //Alice要尽可能大,所以取-INF
for(int i = 0; i < 3; i ++ )
for(int j = 0; j < 3; j ++ )
if(!g[i][j]) //没有被下,就下在这里
{
g[i][j] = 1;
res=max(res,dfs(1));
g[i][j] = 0; //回溯
}
return res;
}
else
{
int res=INF; //Bob要尽可能小,所以取INF
for(int i = 0; i < 3; i ++ )
for(int j = 0; j < 3; j ++ )
if(!g[i][j]) //没有被下,就下在这里
{
g[i][j]=2;
res=min(res, dfs(0));
g[i][j] = 0; //回溯
}
return res;
}
}
int main()
{
int T;
cin>>T;
while(T--)
{
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
cin>>g[i][j];
cout<<dfs(0)<<endl;
}
return 0;
}