题目链接:http://118.190.20.162/view.page?gpid=T70
问题描述
试题编号: | 201803-4 |
试题名称: | 棋局评估 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 Alice和Bob正在玩井字棋游戏。 输入格式 输入的第一行包含一个正整数T,表示数据的组数。 输出格式 对于每组数据,输出一行一个整数,表示当前局面的得分。 样例输入 3 样例输出 3 样例说明 第一组数据: 数据规模和约定 对于所有评测用例,1 ≤ T ≤ 5。 |
思路:这道题标程应该是对抗搜索中的极大极小搜索,前几天集训时刚讲过,不过窝太弱了,没有学会。这道题看了很多博客,最后觉得这位大牛写的极大极小搜索简单易懂,安利一下:https://blog.csdn.net/qq_40400202/article/details/81018053
代码:
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn=1e9;
const int minn=-1e9;
int a[10][10];
bool check(int k)
{
for(int i=1;i<=3;i++)
{
if(a[i][1]==k&&a[i][2]==k&&a[i][3]==k)
return true;
if(a[1][i]==k&&a[2][i]==k&&a[3][i]==k)
return true;
}
if(a[1][1]==k&&a[2][2]==k&&a[3][3]==k)
return true;
if(a[1][3]==k&&a[2][2]==k&&a[3][1]==k)
return true;
return false;
}
int dfs(int k)
{
int cnt=0;
int Max=minn;
int Min=maxn;
for(int i=1;i<=3;i++)
{
for(int j=1;j<=3;j++)
{
if(a[i][j]==0)
cnt++;
}
}
if((k==1)&&check(2))
return -cnt-1;
if((k==2)&&check(1))
return cnt+1;
if(cnt==0)
return 0;
for(int i=1;i<=3;i++)
{
for(int j=1;j<=3;j++)
{
if(a[i][j]==0)
{
a[i][j]=k;
if(k==1)
{
Max=max(Max,dfs(2));
}
else
{
Min=min(Min,dfs(1));
}
a[i][j]=0;
}
}
}
if(k==1)
return Max;
else
return Min;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
for(int i=1;i<=3;i++)
{
for(int j=1;j<=3;j++)
{
scanf("%d",&a[i][j]);
}
}
cout << dfs(1) << endl;
}
return 0;
}