博弈搜索, Alpha−Beta 剪枝
Alpha−Beta 剪枝:
令
alpha
=
max
{
beta
=
如果在搜索的过程中, beta<=alpha ,那么 beta 对 alpha 的值将没有贡献,对 beta 不必继续搜索。
同理,如果 alpha′>=beta ,那么 alpha′ 对 beta 的值将没有贡献,对 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;
}