poj 1568 分类: poj templates 2015-08-08 16:09 6人阅读 评论(0) 收藏


博弈搜索,AlphaBeta 剪枝


AlphaBeta 剪枝:

alpha = max{beta = min{alpha}}

如果在搜索的过程中,beta<=alpha,那么betaalpha的值将没有贡献,对 beta 不必继续搜索。

同理,如果 alpha>=beta,那么alphabeta的值将没有贡献,对 alpha 不必继续搜索。


本题还有特殊的特判技巧,然而并不会证明。。。


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <string>
#include <map>
#include <vector>
#include <stack>
#include <queue>
#include <utility>
#include <iostream>
#include <algorithm>

template<class Num>void read(Num &x)
{
    char c; int flag = 1;
    while((c = getchar()) < '0' || c > '9')
        if(c == '-') flag *= -1;
    x = c - '0';
    while((c = getchar()) >= '0' && c <= '9')
        x = (x<<3) + (x<<1) + (c-'0');
    x *= flag;
    return;
}
template<class Num>void write(Num x)
{
    if(x < 0) putchar('-'), x = -x;
    static char s[20];int sl = 0;
    while(x) s[sl++] = x%10 + '0',x /= 10;
    if(!sl) {putchar('0');return;}
    while(sl) putchar(s[--sl]);
}

const int size = 10, Win = 1, Node = 1, Empty = 0;


int map[size][size], tot;

int MaxSearch(int step,int beta);
int MinSearch(int step,int alpha);

bool check_end()
{
    int cntx = 0, cnty = 0;

    for(int i = 0; i < 4; i++)
    {
        cntx += map[i][i];
        cnty += map[i][3 - i];
    }

    if(cntx == 4 || cntx == -4) return true;
    if(cnty == 4 || cnty == -4) return true;    

    for(int i = 0; i < 4; i++)
    {
        cntx = 0, cnty = 0;
        for(int j = 0; j < 4; j++)
        {
            cntx += map[i][j];
            cnty += map[j][i];
        }
        if(cntx == 4 || cntx == -4) return true;
        if(cnty == 4 || cnty == -4) return true;    
    }

    return false;
}

int MaxSearch(int step,int beta)
{
    if(step == 16) return Empty;
    if(check_end()) return -Win;

    int alpha = -Win;

    for(int i = 0; i < 4; i++)
        for(int j = 0; j < 4; j++)
            if(!map[i][j])
            {
                map[i][j] = Node;
                alpha = std::max(MinSearch(step + 1, alpha), alpha);
                map[i][j] = Empty;

                if(alpha >= beta) return alpha; 
            }
    return alpha;       
}
int MinSearch(int step,int alpha)
{
    if(step == 16) return Empty;
    if(check_end()) return Win;

    int beta = Win;

    for(int i = 0; i < 4; i++)
        for(int j = 0; j < 4; j++)
            if(!map[i][j])
            {
                map[i][j] = -Node;
                beta = std::min(MaxSearch(step + 1, beta), beta);
                map[i][j] = Empty;

                if(beta <= alpha) return beta;
            }
    return beta;
}

bool solve()
{
    int alpha = 0;

//  if(tot <= 4) return alpha;

    for(int i = 0; i < 4; i++)
        for(int j = 0; j < 4; j++)
            if(!map[i][j])
            {
                map[i][j] = Node;
                alpha = std::max(MinSearch(tot + 1, alpha), alpha);
                map[i][j] = Empty;

                if(alpha > 0)
                {
                    putchar('('), putchar(i + '0'), putchar(',');
                    putchar(j + '0'), putchar(')'), puts("");

                    return alpha;
                }
            }
    return alpha;
}

void init()
{
    char ch[size][size];

    for(int i = 0; i < 4; i++) scanf("%s",ch[i]);

    tot = 0;

    for(int i = 0; i < 4; i++)
        for(int j = 0; j < 4; j++)
        {
            map[i][j] = ((ch[i][j] == 'x')?1:(ch[i][j] == 'o'?-1:0));   

            if(map[i][j]) tot++;
        }
}

int main()
{   
#ifndef ONLINE_JUDGE
    freopen("1568.in","r",stdin);
    freopen("1568.out","w",stdout);
#endif

    while(true)
    {
        char c[5];

        scanf("%s",c);

        if(c[0] == '$') break;

        init();

        if(!solve()) puts("#####");
    }

#ifndef ONLINE_JUDGE
    fclose(stdin);
    fclose(stdout);
#endif
    return 0;       
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2015-08-08 16:09  <Dash>  阅读(94)  评论(0编辑  收藏  举报