zoukankan      html  css  js  c++  java
  • poj1568 Find the Winning Move[极大极小搜索+alpha-beta剪枝]

    Find the Winning Move
    Time Limit: 3000MS   Memory Limit: 32768K
    Total Submissions: 1286   Accepted: 626

    Description

    4x4 tic-tac-toe is played on a board with four rows (numbered 0 to 3 from top to bottom) and four columns (numbered 0 to 3 from left to right). There are two players, x and o, who move alternately with x always going first. The game is won by the first player to get four of his or her pieces on the same row, column, or diagonal. If the board is full and neither player has won then the game is a draw. 
    Assuming that it is x's turn to move, x is said to have a forced win if x can make a move such that no matter what moves o makes for the rest of the game, x can win. This does not necessarily mean that x will win on the very next move, although that is a possibility. It means that x has a winning strategy that will guarantee an eventual victory regardless of what o does. 

    Your job is to write a program that, given a partially-completed game with x to move next, will determine whether x has a forced win. You can assume that each player has made at least two moves, that the game has not already been won by either player, and that the board is not full. 

    Input

    The input contains one or more test cases, followed by a line beginning with a dollar sign that signals the end of the file. Each test case begins with a line containing a question mark and is followed by four lines representing the board; formatting is exactly as shown in the example. The characters used in a board description are the period (representing an empty space), lowercase x, and lowercase o. For each test case, output a line containing the (row, column) position of the first forced win for x, or '#####' if there is no forced win. Format the output exactly as shown in the example.

    Output

    For this problem, the first forced win is determined by board position, not the number of moves required for victory. Search for a forced win by examining positions (0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), ..., (3, 2), (3, 3), in that order, and output the first forced win you find. In the second test case below, note that x could win immediately by playing at (0, 3) or (2, 0), but playing at (0, 1) will still ensure victory (although it unnecessarily delays it), and position (0, 1) comes first.

    Sample Input

    ?
    ....
    .xo.
    .ox.
    ....
    ?
    o...
    .ox.
    .xxx
    xooo
    $

    Sample Output

    #####
    (0,1)
    

    Source

     

    #include<cstdio>
    using namespace std;
    char s[5][5];
    int chess,X,Y;
    inline int abs(int x){return x>0?x:-x;}
    bool check(int x,int y){//判断一个局面是否结束
        int tot=0;
        for(int i=0;i<4;i++) s[x][i]=='o'?tot++:s[x][i]=='x'?tot--:tot;//横向判断
        if(abs(tot)==4) return 1;tot=0;
        for(int i=0;i<4;i++) s[i][y]=='o'?tot++:s[i][y]=='x'?tot--:tot;//纵向判断
        if(abs(tot)==4) return 1;tot=0;
        for(int i=0;i<4;i++) s[i][i]=='o'?tot++:s[i][i]=='x'?tot--:tot;//正对角线判断
        if(abs(tot)==4) return 1;tot=0;
        for(int i=0;i<4;i++) s[i][3-i]=='o'?tot++:s[i][3-i]=='x'?tot--:tot;//反对角线判断
        if(abs(tot)==4) return 1;
        return 0;
    }
    int Min(int ,int);
    int Max(int ,int);
    int Max(int x,int y){
        if(check(x,y)) return -1;//已经结束(对方胜)
        if(chess==16) return 0;//平局
        for(int i=0,now;i<4;i++){
            for(int j=0;j<4;j++){
                if(s[i][j]=='.'){
                    s[i][j]='x';chess++;
                    now=Min(i,j);
                    s[i][j]='.';chess--;
                    //对方需要找的最差估价,如果当前比之前最差的高,α剪枝
                    if(now==1) return 1;
                }
            }
        }
        return -1;
    }
    int Min(int x,int y){
        if(check(x,y)) return 1;//已经结束(己方胜)
        if(chess==16) return 0;
        for(int i=0,now;i<4;i++){
            for(int j=0;j<4;j++){
                if(s[i][j]=='.'){
                    s[i][j]='o';chess++;
                    now=Max(i,j);
                    s[i][j]='.';chess--;
                    //自己需要找的最高估价,如果当前比之前最差的低,β剪枝
                    if(!now||now==-1) return -1;
                }
            }
        }
        return 1;
    }
    bool solve(){
        for(int i=0,now;i<4;i++){
            for(int j=0;j<4;j++){//枚举,然后搜索
                if(s[i][j]=='.'){
                    s[i][j]='x';chess++;
                    now=Min(i,j);
                    s[i][j]='.';chess--;
                    if(now==1){
                        X=i;Y=j;
                        return 1;
                    }
                }
            }
        }
        return 0;
    }
    int main(){
        char ch[3];
        while(~scanf("%s",ch)&&ch[0]=='?'){
            for(int i=0;i<4;i++) scanf("%s",s[i]);chess=0;
            for(int i=0;i<4;i++) for(int j=0;j<4;j++) chess+=s[i][j]!='.'; 
            if(chess<=4){puts("#####");continue;}//一定平局(对方都绝顶聪明的话) 
            if(solve()) printf("(%d,%d)
    ",X,Y);
            else puts("#####");
        }
        return 0;
    }
  • 相关阅读:
    虚拟主机导入MySQL出现Unknown character set: ‘utf8mb4’
    解决导入MySQL数据库提示"Unknown character set: 'utf8mb4'"错误
    织梦dedecms如何去除版权中的Power by DedeCms
    发送邮件常见出错代码及简单解决方法
    Hadoop集群配置(最全面总结)
    大数据下的数据分析平台架构
    跟上节奏 大数据时代十大必备IT技能
    Hive深入浅出
    深入解析:分布式系统的事务处理经典问题及模型(转载分享)
    数据分析≠Hadoop+NoSQL
  • 原文地址:https://www.cnblogs.com/shenben/p/6701098.html
Copyright © 2011-2022 走看看