POJ 1568 四子棋 搜索剪枝

题意:给定一个四子棋的棋盘,问是否存在先手必胜的策略

思路:极大极小算法。暴力搜索会T,这里加上剪枝,当发现 a>=b 时可以直接返回,这里a>=b证明找到一种合理策略,最后再用全局变量保存一下结果就可以。

点击打开链接

#include
#include
#include
#define debug puts("%%%%%")
#define read(x) scanf("%d",&x)
using namespace std;
char ma[5][5];
int ax,ay;
int judge() {
    int xa=0,xb=0,ya=0,yb=0;
    for(int i=0;i<4;i++) {
        int ra=0,rb=0,ca=0,cb=0;
        if(ma[i][i]=='x')xa+=1;
        else if(ma[i][i]=='o')xb+=1;
        if(ma[i][3-i]=='x')ya+=1;
        else if(ma[i][3-i]=='o')yb+=1;
        for(int j=0;j<4;j++) {
            if(ma[i][j]=='x') ra+=1;
            else if(ma[i][j]=='o') rb+=1;
            if(ma[j][i]=='x') ca+=1;
            else if(ma[j][i]=='o') cb+=1;
        }
        if(ra==4 || ca==4 || xa==4 || ya==4)return 1;
        else if(rb==4 || cb==4 || xb==4 || yb==4) return -1;
    }
    return 0;
}
int ab(int p,int a,int b) {
    int f=judge();
    if(f) return f;
    if(p) {
        for(int i=0;i<4;i++) {
            for(int j=0;j<4;j++) {
                if(ma[i][j]=='.') {
                    int v;
                    ma[i][j]='x';
                    v=ab(p^1,a,b);
                    ma[i][j]='.';
                    if(v > a) {
                        a=v;
                        ay=i;
                        ax=j;
                    }
                    if(a>=b) {
                        return a;
                    }
                }
            }
        }
        return a;
    }
    else {
        for(int i=0;i<4;i++) {
            for(int j=0;j<4;j++) {
                if(ma[i][j]=='.') {
                    int v;
                    ma[i][j]='o';
                    v=ab(p^1,a,b);
                    ma[i][j]='.';
                    if(v=b) {
                        return b;
                    }
                }
            }
        }
        return b;
    }
}
int main() {
    char cc[2];
    while(scanf("%s",cc),cc[0]!='$') {
        int a=-1;
        int b=1;
        int ans,count=0;
        for(int i=0;i<4;i++) {
            scanf("%s",ma[i]);
            for(int j=0;j<4;j++) {
                if(ma[i][j]!='.')count++;
            }
        }
        if(count<=4){
            printf("#####\n");
            continue;
        }
        ans=ab(1,a,b);
        if(ans>0) {
            printf("(%d,%d)\n",ay,ax);
        }
        else{
            printf("#####\n");
        }
    }
}

你可能感兴趣的:(搜索)