CCF 201803-4 棋局評估 極大極小搜尋
阿新 • • 發佈:2019-01-05
題意:3X3的井字棋,1先走,2後走,給定一個狀態。當前輪到1走,1,2都按照最優策略行棋,求最後的分數。
#include <cstdio>
#include <algorithm>
using namespace std;
const int INF = 100;
int a[10];
int check()
{
int cnt = 0;
for(int i = 1; i <= 9; ++i) if(!a[i]) ++cnt;
for(int i = 1; i <= 3; ++i)
if(a[i]==1&&a[i+3 ]==1&&a[i+6]==1) return cnt+1;
else if(a[i]==2&&a[i+3]==2&&a[i+6]==2) return -cnt-1;
for(int i = 1; i <= 7; i+=3)
if(a[i]==1&&a[i+1]==1&&a[i+2]==1) return cnt+1;
else if(a[i]==2&&a[i+1]==2&&a[i+2]==2) return -cnt-1 ;
if(a[1]==1&&a[5]==1&&a[9]==1) return cnt+1;
if(a[1]==2&&a[5]==2&&a[9]==2) return -cnt-1;
if(a[3]==1&&a[5]==1&&a[7]==1) return cnt+1;
if(a[3]==2&&a[5]==2&&a[7]==2) return -cnt-1;
if(cnt==0) return 0;//point!!!
return INF; //point!!!
}
int dfs(int turn)
{
int value = check();
if(value != INF) return value;
int ret;
if(turn==1) ret = -INF;
else ret = INF;
for(int i = 1; i <= 9; ++i)
{
if(a[i]) continue;
if(turn==1)
{
a[i] = 1;
ret = max(ret, dfs(0));
}
else
{
a[i] = 2;
ret = min(ret, dfs(1));
}
a[i] = 0;
}
return ret;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
for(int i = 1; i <= 9; ++i) scanf("%d", &a[i]);
printf("%d\n", dfs(1));
}
return 0;
}