思路:
这道题逻辑必须非常清晰才能做出来。首先要明白这是一个博弈论的问题,也就是说,你的对手希望他得高分,你希望你得高分,可是你分数高了他的分就低了,所以是一种博弈。
下棋的时候,你希望走出最好的局面,即使输也要分数最高,而你的对手恰恰相反,他要走出他的最好局面,也就是你的最坏局面,让你分数最低。
这样交替行棋,也就完成了对棋局的推演,得出高手的最终局势。
这本质上是博弈论中的对抗搜索,有不懂的地方可以自行百度。
#include<bits/stdc++.h>
using namespace std;
int chess[3][3];
int canwin(){ //判断局势
int victory=0;
int temp;
for(temp=1;temp<3;temp++){
int flag;
//纵横是否成棋
for(int i=0;i<3;i++){
flag=1;
for(int j=0;j<3;j++){
if(chess[i][j]!=temp){
flag=0;
break;
}
}
if(flag==1){
victory=1;
break;
}
flag=1;
for(int j=0;j<3;j++){
if(chess[j][i]!=temp){
flag=0;
break;
}
}
if(flag==1){
victory=1;
break;
}
}
if(flag==1){
victory=1;
break;
}
//对角线是否成棋
flag=1;
for(int i=0;i<3;i++){
if(chess[i][i]!=temp){
flag=0;
break;
}
}
if(flag==1){
victory=1;
break;
}
flag=1;
for(int i=0;i<3;i++){
if(chess[i][2-i]!=temp){
flag=0;
break;
}
}
if(flag==1){
victory=1;
break;
}
}
if(victory==1)return temp;
else return -1;
}
int zeronum(){ //统计空位个数
int num=0;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if(chess[i][j]==0)num++;
}
}
return num;
}
int score(){ //分数计算
int win=canwin(),ans=zeronum()+1;
switch(win){
case -1:
return 0;
break;
case 1:
return ans;
break;
case 2:
return -ans;
break;
}
}
int dfs(int stone){ //深度(对抗)搜索
if(!zeronum())return 0; //棋盘已满 和棋
int maxs=-100,mins=100;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if(!chess[i][j]){ //寻找落子位置
chess[i][j]=stone; //落子有悔
int ans=score(); //判断是否获胜 并得出相应分数
if(ans){ //若获胜
chess[i][j]=0; //悔棋
return ans; //返回分数
}
if(stone==1) maxs=max(maxs,dfs(2));//Bob行棋 返回最小的分数 也即对Bob最有利的分数
else mins=min(mins,dfs(1));//Alice行棋 返回最大的分数 也即对Alice最有利的分数
chess[i][j]=0; //悔棋
}
}
}
return stone==1? maxs:mins; //0-Alice-Max,1-Bob-Min
}
int main(){
int T;
cin>>T;
while(T--){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
chess[i][j]=0;
}
}
//输入
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
cin>>chess[i][j];
}
}
//处理
int t=score();
if(t){ //判断是否为定势
cout<<t<<endl;
continue;
}
t=dfs(1); //Alice行棋
//输出
cout<<t<<endl; //输出
}
}
样例:
/*
样例输入
3
1 2 1
2 1 2
0 0 0
2 1 1
0 2 1
0 0 2
0 0 0
0 0 0
0 0 0
5
1 1 1
2 1 2
0 0 0
2 1 1
0 2 1
0 0 2
2 2 2
1 2 1
2 0 1
2 1 1
0 2 1
2 1 1
0 0 0
0 0 0
0 0 0
1
1 2 0
0 0 0
0 0 0
*/