POJ 1568 (alpha-beta 剪枝)

Description:

在四子棋游戏中,两个人的棋盘分别被表示为'O'和'X', 现在给出一个局面,假设下一步为'X'走,问是否有哪一步使得‘X’必胜,若有则输出该位置。

Input:

一个4*4字符矩阵,代表棋盘局面

Output:

若存在必胜位置输出(X,Y)坐标,否则输出'#####'.

Analysis:

直接套用alpha-beta 剪枝即可。

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<stack>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<sstream>
#include<cmath>
#include<iterator>
#include<bitset>
#include<stdio.h>
#include<time.h>
using namespace std;
#define _for(i,a,b) for(int i=(a);i<(b);++i)
#define _rep(i,a,b) for(int i=(a);i<=(b);++i)
typedef long long LL;
const int INF = 0xffffff0;
const int MOD = 1e9 + 7;
const int maxn = 10005;

char pic[5][5];
int X, Y, chess;
int MinSearch(int x, int y, int alpha);
int MaxSearch(int x, int y, int beta);

int dx[] = { 1,0,1,-1 };
int dy[] = { 0,1,1,1, };

inline bool inside(int x, int y) {
	return x >= 0 && x<4 && y >= 0 && y<4;
}

bool check(int x, int y) {
	char op = pic[x][y];
	for (int dir = 0; dir<4; ++dir) {
		int cnt = 1;
		int nowx = x, nowy = y;
		while (inside(nowx + dx[dir], nowy + dy[dir])) {
			nowx += dx[dir], nowy += dy[dir];
			if (pic[nowx][nowy] == op) {
				cnt++;
			}
			else break;
		}
		nowx = x, nowy = y;
		while (inside(nowx - dx[dir], nowy - dy[dir])) {
			nowx -= dx[dir], nowy -= dy[dir];
			if (pic[nowx][nowy] == op) {
				cnt++;
			}
			else break;
		}
		if (cnt >= 4)return true;
	}
	return false;
}
int MinSearch(int x, int y, int alpha) {
	int ans = INF;
	if (check(x, y))
		return INF;
	if (chess == 16)
		return 0;
	for (int i = 0; i<4; ++i)
		for (int j = 0; j<4; ++j) {
			if (pic[i][j] == '.') {
				pic[i][j] = 'o'; ++chess;
				int tmp = MaxSearch(i, j, ans);
				pic[i][j] = '.'; --chess;
				ans = min(ans, tmp);
				if (ans <= alpha) {
					return ans;
				}
			}
		}
	return ans;
}

int MaxSearch(int x, int y, int beta) {
	int ans = -INF;
	if (check(x, y))
		return -INF;
	if (chess == 16)
		return 0;
	for (int i = 0; i<4; ++i)
		for (int j = 0; j<4; ++j) {
			if (pic[i][j] == '.') {
				pic[i][j] = 'x'; ++chess;
				int tmp = MinSearch(i, j, ans);
				pic[i][j] = '.'; --chess;
				ans = max(tmp, ans);
				if (ans >= beta)
					return ans;
			}
		}
	return ans;
}

bool Solve() {
	int alpha = -INF;
	for (int i = 0; i<4; ++i)
		for (int j = 0; j<4; ++j) {
			if (pic[i][j] == '.') {
				pic[i][j] = 'x'; chess++;
				int tmp = MinSearch(i, j, alpha);
				pic[i][j] = '.'; chess--;
				if (tmp == INF) {
					X = i;
					Y = j;
					return true;
				}
			}
		}
	return false;
}

int main() {
	//freopen("C:\\Users\\admin\\Desktop\\in.txt", "r", stdin);
	//freopen("C:\\Users\\admin\\Desktop\\out.txt", "w", stdout);

	char s[5];
	while (scanf("%s", s) != EOF && s[0] != '$') {
		chess = 0;
		for (int i = 0; i<4; ++i) {
			scanf("%s", pic[i]);
			for (int j = 0; j<4; ++j)
				chess += pic[i][j] != '.';
		}
		if (chess <= 4) {
			printf("#####\n");
			continue;
		}
		if (Solve())printf("(%d,%d)\n", X, Y);
		else printf("#####\n");
	}

	return 0;
}

猜你喜欢

转载自blog.csdn.net/tomandjake_/article/details/81282131