问题描述
试题编号: | 201803-4 |
试题名称: | 棋局评估 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 Alice和Bob正在玩井字棋游戏。 输入格式 输入的第一行包含一个正整数T,表示数据的组数。 输出格式 对于每组数据,输出一行一个整数,表示当前局面的得分。 样例输入 3 样例输出 3 样例说明 第一组数据: 数据规模和约定 对于所有评测用例,1 ≤ T ≤ 5。 |
递归回溯所有可能的情况。
①Alice胜评估得分是正的,取最大值
②Bob胜评估得分是负的,取最小值
③平局是0分
AC代码:
#include<iostream>
#include<string>
using namespace std;
int cb[4][4];//chessbocbrd
bool isvictory(int k)//判断k是否赢了,k=1代表cblice,k=2代表bob;
{
int i;
for(i=1;i<=3;i++)
{
if((cb[i][1]==cb[i][2])&&(cb[i][2]==cb[i][3])&&(cb[i][3]==k))return true; //一行
if((cb[1][i]==cb[2][i])&&(cb[2][i]==cb[3][i])&&(cb[3][i]==k))return true; //一列
}
if((cb[1][1]==k)&&(cb[2][2]==k)&&(cb[3][3]==k))return true;//主对角
if((cb[1][3]==k)&&(cb[2][2]==k)&&(cb[3][1]==k))return true;//副对角
return false; //其他情况
}
int dfs(int k)//轮到k下棋,判断棋盘局势,返回最终状态的得分
{
int t=0;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
if(cb[i][j]==0) t++; //计算出棋盘中空格数
if(k==1&&isvictory(2))return -t-1; //因为bob赢了,要加上一个负号;
if(k==2&&isvictory(1))return t+1;
if(t==0) return 0; //平局
int mn=10000000,mx=-10000000;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
if(cb[i][j]==0)//对每一个空格进行模拟;
{
cb[i][j]=k;
if(k==1) mx=max(mx,dfs(2));//这个就是为了要满足最优下棋策略的语句,就是alice会选择下一步最优的解;
if(k==2) mn=min(mn,dfs(1));//同理
cb[i][j]=0;//回溯前面的状态;
}
//进行到这一步,对所有空格都进行了模拟,返回相应的最值
if(k==1) return mx;
if(k==2) return mn;
}
int main()
{
int ans,n;
cin>>n;
while(n--)
{
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
cin>>cb[i][j];
ans=dfs(1); //Alice先下棋
cout<<ans<<endl;
}
return 0;
}
参考自https://blog.csdn.net/qq_40400202/article/details/81018053