博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 1568 Find the Winning Move(极大极小搜索)
阅读量:7058 次
发布时间:2019-06-28

本文共 1799 字,大约阅读时间需要 5 分钟。

题目链接:

题意:给出一个4*4的棋盘,x和o两人轮流放。先放够连续四个的赢。给定一个局面,下一个轮到x放。问x是否有必胜策略?若有,输出能够赢的最小的坐标?

思路:(1)Maxfind(Min):每次放x,若得到的Max大于等于Min,则直接返回Max。因为Minfind要用这个Max更新Min,若x放置之后能够得到一个比Min大的,显然这样放最好;因为Min无法用Max更新;

(2)Minfind(Max)类似;

(3)因此,枚举第一个人放的位置,Minfind,返回的是INF则胜利。

 

char s[10][10];
int ansX,ansY,chessCnt;
int isOver(int x,int y)
{
    int r[4]={0},c[4]={0},i,j;
    clr(r,0); clr(c,0);
    FOR0(i,4) FOR0(j,4)
    {
        if(s[i][j]=='x') r[i]++,c[j]++;
        if(s[i][j]=='o') r[i]--,c[j]--;
    }
    if(abs(r[x])==4||abs(c[y])==4) return 1;
    int cnt1=0,cnt2=0;
    FOR0(i,4)
    {
        if(s[i][i]=='x') cnt1++;
        if(s[i][3-i]=='x') cnt2++;
        if(s[i][i]=='o') cnt1--;
        if(s[i][3-i]=='o') cnt2--;
    }
    if(abs(cnt1)==4&&x==y||abs(cnt2)==4&&x+y==3) return 1;
    return 0;
}
int Minfind(int,int,int);
int Maxfind(int x,int y,int Min)
{
    int temp,Max=-INF,i,j;
    if(isOver(x,y)) return Max;
    if(chessCnt==16) return 0;
    FOR0(i,4) FOR0(j,4) if(s[i][j]=='.')
    {
        s[i][j]='x';
        chessCnt++;
        temp=Minfind(i,j,Max);
        chessCnt--;
        s[i][j]='.';
        if(temp>Max) Max=temp;
        if(Max>=Min) return Max;
    }
    return Max;
}
int Minfind(int x,int y,int Max)
{
    int temp,Min=INF,i,j;
    if(isOver(x,y)) return Min;
    if(chessCnt==16) return 0;
    FOR0(i,4) FOR0(j,4) if(s[i][j]=='.')
    {
        s[i][j]='o';
        chessCnt++;
        temp=Maxfind(i,j,Min);
        chessCnt--;
        s[i][j]='.';
        if(temp<Min) Min=temp;
        if(Min<=Max) return Min;
    }
    return Min;
}
int check()
{
    int Max=-INF,i,j,temp;
    FOR0(i,4) FOR0(j,4) if(s[i][j]=='.')
    {
        s[i][j]='x';
        chessCnt++;
        temp=Minfind(i,j,Max);
        chessCnt--;
        s[i][j]='.';
        if(temp>Max) Max=temp,ansX=i,ansY=j;
        if(Max==INF) return 1;
    }
    return 0;
}
int main()
{
    char op[5];
    while(scanf("%s",op)&&op[0]!='$')
    {
        int i,j;
        chessCnt=0;
        FOR0(i,4)
        {
            RD(s[i]);
            FOR0(j,4) chessCnt+=s[i][j]!='.';
        }
        if(chessCnt<=4||!check()) puts("#####");
        else printf("(%d,%d)\n",ansX,ansY);
    }
}

转载于:https://www.cnblogs.com/jianglangcaijin/p/3452877.html

你可能感兴趣的文章
8月共处理钓鱼网站1862个:非CN域名达1855个
查看>>
网络数据安全
查看>>
Hello World
查看>>
open***
查看>>
开启golang之旅
查看>>
Android TableLayout表格布局
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
购物车--low版
查看>>
linux
查看>>
LINQ分页和排序,skip和Take 用法
查看>>
Activiti 查找流程状态(流程下一步)
查看>>
Angular UI Route
查看>>
一个应届毕业生程序员的独白
查看>>
编译安装ZABBIX客户端(代理)
查看>>
jsp下拉框中显示数据库信息&&jsp 下拉框从数据库中如何取值?
查看>>
Linux系统编程 --- 共享内存及内存映射【十全十美】
查看>>
H5页面快速搭建之高级字体应用实践
查看>>
centos6.5、centos6.6修改ssh默认端口号
查看>>
文本文件和二进制文件
查看>>