版权声明: https://blog.csdn.net/leelitian3/article/details/82533612
思路
①当Alice下的时候,我们尝试所有可能的下法,并找到所有下法中使结果最大的一个
当Bob下的时候,我们尝试所有可能的下法,并找到所有下法中使结果最小的一个
②轮流执子,直到双方有人胜利或棋盘填满
蒟蒻我还是不能很好的表达出意思来...QAQ
C++满分代码(带注释)
#include <iostream>
using namespace std;
const int inf = 1e8;
int chess[3][3];
inline int Score() //返回棋局的得分,若未结束则返回inf
{
int blank = 0; //空格数
for(int i=0; i<3; ++i)
for(int j=0; j<3; ++j)
if(chess[i][j] == 0) ++blank;
int flag = (blank & 1 ? -1 : 1); //空格数为偶数,说明走了奇数步,这时Bob可能要赢了,故flag=-1
for(int i=0; i<3; ++i)
if(chess[i][0]==chess[i][1] && chess[i][1]==chess[i][2] && chess[i][0]) return flag*(blank+1);
for(int j=0; j<3; ++j)
if(chess[0][j]==chess[1][j] && chess[1][j]==chess[2][j] && chess[2][j]) return flag*(blank+1);
if(chess[0][0]==chess[1][1] && chess[1][1]==chess[2][2] && chess[2][2]) return flag*(blank+1);
if(chess[2][0]==chess[1][1] && chess[1][1]==chess[0][2] && chess[0][2]) return flag*(blank+1);
if(blank == 0) return 0; //如果没人赢,又下满了,则为平局
return inf;
}
inline int search(int a) //下面以Alice为例进行说明,Bob在(*)处正好相反
{
int score = Score();
if(score != inf) return score; //若结束,返回分数
int optimal = (a == 1 ? -inf : inf), tmp; //optimal初始化为-inf,Alice要使optimal达到最大 (*)
for(int i=0; i<3; ++i)
for(int j=0; j<3; ++j)
{
if(chess[i][j] == 0) //对所有空格子进行尝试
{
chess[i][j] = a;
tmp = (a == 1 ? search(2) : search(1)); //Alice下完Bob下 (*)
if(a == 1) optimal = max(tmp, optimal); //optimal取较大者 (*)
else optimal = min(tmp, optimal);
chess[i][j] = 0; //尝试之后记得复原
}
}
return optimal;
}
int main()
{
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--)
{
for(int i=0; i<3; ++i) //输入
for(int j=0; j<3; ++j)
cin>>chess[i][j];
cout<<search(1)<<"\n"; //输出
}
return 0;
}