题意:
给你一个井字棋局面,判断当前得分。
题解:
对抗搜索
代码如下:
#include<bits/stdc++.h>
using namespace std;
unordered_map<string,int>grade;
int dir[8][2]={{1,0},{-1,0},{0,1},{0,-1},{1,1},{-1,-1},{-1,1},{1,-1}},cntA[4];
bool flag;
bool check_range(int x,int y){
if(x<0||x>=3||y<0||y>=3)return false;
return true;
}
bool checkPos(string s,int now){
int i,x,y,dx,dy,oth;
x=now/3;y=now%3;
for (i=0;i<4;i++)cntA[i]=0;
for (i=0;i<8;i++){
dx=x+dir[i][0];dy=y+dir[i][1];
if(!check_range(dx,dy))continue;
oth=dx*3+dy;
if(s[now]!=s[oth])continue;
if(i<2)cntA[0]++;
else if(i<4)cntA[1]++;
else if(i<6)cntA[2]++;
else cntA[3]++;
}
if(cntA[0]==2)return true;
if(cntA[1]==2)return true;
if(cntA[2]==2)return true;
if(cntA[3]==2)return true;
return false;
}
int getGrade(string s){
int i,ret;
ret=0;
for(i=0;i<9;i++)if(s[i]=='0')ret++;ret++;
for(i=0;i<9;i++){
if(s[i]=='0')continue;
if(!checkPos(s,i))continue;
if(s[i]=='2')ret*=-1;
return ret;
}
return 0;
}
int getBlank(string s){
int ret=0,i;
for (i=0;i<9;i++)if(s[i]=='0')ret++;
return ret;
}
int dfs(string s,int which){
int i,ret,ans;
if(grade.find(s)!=grade.end())return grade[s];
ret=getGrade(s);
if(ret){
grade[s]=ret;return ret;
}
if(!getBlank(s)){
grade[s]=0;return 0;
}
ans=which?-20:20;
for (i=0;i<9;i++){
if(s[i]!='0')continue;
s[i]=which?'1':'2';
ans=which?(max(ans,dfs(s,1-which))):(min(ans,dfs(s,1-which)));
s[i]='0';
}
grade[s]=ans;
return ans;
}
int main(){
int i,j,tCase,tmp;
string s;
grade.clear();
scanf("%d",&tCase);
while(tCase--){
s="";
for(i=1;i<=3;i++)for(j=1;j<=3;j++)scanf("%d",&tmp),s+=(tmp+'0');
dfs(s,1);
printf("%d\n",grade[s]);
}
return 0;
}