POJ 1568(极大极小值搜索)

题目链接:点击打开链接


题目大意:给出一个4*4棋盘,问你x先手的情况下,是否能实现必胜(胜利条件是横着或竖着或斜着出现四连)


题目思路:第一道极大极小值搜索题目...首先一个强大的剪枝,如果下的步数小于等于4,那么肯定可以平局(好像是井字棋特性),然后极大极小值搜索。


极大极小值搜索介绍:

极大极小值搜索靠的是返回的数值,每个人下一步,到最后如果返回1就说明必胜,否则就不一定必胜。因为要判断是否必胜,所以每一步都要走一下,step表示还能走几步。然后首先先找一下有没有可以下的点,有的话就下下去,然后递归下一步,给对方下,刚开始要写个value函数,就是判断当前局面有没有人赢了。val是用来看后面状态的情况,z是当前的情况,刚开始先把z变成不利于己方的情况,然后不断递归,看下面的局势,如果后面可以必胜,那z就会通过val的值不断更新,后面如果赢了或者输了前面就能知道了。


以下是代码:

#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char cmd[1],map1[10][10],x,y;
int value(){
    int h1,h2,s1,s2;
    for(int i=0;i<4;i++){
        h1=0,h2=0,s1=0,s2=0;
        for(int j=0;j<4;j++){
            if(map1[i][j]=='x'){
                h1++;
            }
            if(map1[i][j]=='o'){
                h2++;
            }
            if(map1[j][i]=='x'){
                s1++;
            }
            if(map1[j][i]=='o'){
                s2++;
            }
        }
        if(h1==4||s1==4){
            return 1;
        }
        if(h2==4||s2==4){
            return -1;
        }
    }
    h1=0,h2=0,s1=0,s2=0;
        for(int i=0;i<4;i++){
            if(map1[i][i]=='x'){
                h1++;
            }
            if(map1[i][i]=='o'){
                h2++;
            }
            if(map1[i][3-i]=='x'){
                s1++;
            }
            if(map1[i][3-i]=='o'){
                s2++;
            }
        }
        if(h1==4||s1==4)return 1;
        if(h2==4||s2==4)return -1;
    return 0;
}
int Max(int);
int Min(int step){
    int flag=value(),z=1,val;
    if(flag||step==0){
        return flag;
    }
    for(int i=0;i<4;i++){
        for(int j=0;j<4;j++){
            if(map1[i][j]=='.'){
                map1[i][j]='o';
                val=Max(step-1);
                map1[i][j]='.';
                z=min(val,z);
            }
        }
    }
    return z;
}
int Max(int step){
    int val,z=-1,flag=value();
    if(flag||step==0){
        return flag;
    }
    for(int i=0;i<4;i++){
        for(int j=0;j<4;j++){
            if(map1[i][j]=='.'){
                map1[i][j]='x';
                val=Min(step-1);
                map1[i][j]='.';
                z=max(z,val);
                if(val==1){
                    x=i,y=j;
                    return 1;
                }
            }
        }
    }
    return z;
}
int main()
{
    while(~scanf("%s",cmd)&&cmd[0]!='$'){
        int step=0;
        for(int i=0;i<4;i++){
            scanf("%s",map1[i]);
            for(int j=0;j<4;j++){
                if(map1[i][j]=='.'){
                    step++;
                }
            }
        }
        if(step>11){
            printf("#####\n");
            continue;
        }
        int z=Max(step);
        if(z==1){
            printf("(%d,%d)\n",x,y);
        }
        else{
            printf("#####\n");
        }
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值