链接:http://118.190.20.162/view.page?gpid=T70
思路:判断能不能赢,然后dfs暴力搜
#include <iostream> #include <cstdio> using namespace std; int a[5][5]; int space() { int s=0; for(int i=0; i<3; i++) { for(int j=0; j<3; j++) { if(a[i][j]==0) s++; } } return s; } int pre_judge(int k) { int t=0; for(int i=0; i<3; i++)//判断行和列有没有赢 { if(a[i][0]==k&&a[i][0]==a[i][1]&&a[i][1]==a[i][2]) { t=1; break; } if(a[0][i]==k&&a[0][i]==a[1][i]&&a[1][i]==a[2][i]) { t=1; break; } } //判断斜方有没有赢 if(a[0][0]==k&&a[0][0]==a[1][1]&&a[1][1]==a[2][2]) t=1; if(a[0][2]==k&&a[0][2]==a[1][1]&&a[1][1]==a[2][0]) t=1; if(t)//可以赢就求出得分 { t=space()+1; if(k==2) t=-1*(space()+1); } return t; } int dfs(int k) { if(space()==0)//看还有没有下棋的位置 return 0; int MAX=-10,MIN=10; for(int i=0; i<3; i++) { for(int j=0; j<3; j++) { if(a[i][j]==0)//遍历每一个可以下棋的点 { a[i][j]=k; int t=pre_judge(k);//判断当前点选中时能否赢棋 if(t!=0) { a[i][j]=0; return t>0?max(MAX,t):min(MIN,t); } if(k==1) MAX=max(MAX,dfs(2));//如果是A下棋则下一步该B则可以求出B的分数 else MIN=min(MIN,dfs(1));//如果是B下棋则下一步该A则可以求出A的分数 a[i][j]=0; } } } if(k==1) return MAX;//A下棋的时候返回MAX else return MIN;//B下棋的时候返回MIN } int main() { int t; scanf("%d",&t); while(t--) { for(int i=0; i<3; i++) { for(int j=0; j<3; j++) { scanf("%d",&a[i][j]); } } int x=pre_judge(1);//预先判断现存局面A有没有赢棋 if(x!=0) { cout<<x<<endl; continue; } int o=pre_judge(2);//判断B有没有赢棋 if(o!=0) { cout<<o<<endl; continue; } cout<<dfs(1)<<endl;//搜索 } return 0; }