CCF201803-4-棋局评估

链接: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;
}
AC Code

 

posted @ 2018-09-10 16:21  子诚-  阅读(167)  评论(0编辑  收藏  举报