问题描述
试题编号: | 201803-4 |
试题名称: | 棋局评估 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: |
问题描述 Alice和Bob正在玩井字棋游戏。
输入格式 输入的第一行包含一个正整数T,表示数据的组数。 输出格式 对于每组数据,输出一行一个整数,表示当前局面的得分。 样例输入 3 样例输出 3 样例说明 第一组数据:
数据规模和约定 对于所有评测用例,1 ≤ T ≤ 5。 |
问题分析:https://blog.csdn.net/u014296991/article/details/105611011
极大极小值算法:
c++代码:
#include <iostream>
#define INF 10
int s[4][4];
int minValue(int h);
int spaceNum()
{
int n = 0;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (s[i][j] == 0)
++n;
}
}
return n;
}
bool terminalTest()
{
if ((s[0][0] != 0 && s[0][0] == s[0][1] && s[0][0] == s[0][2]) ||
(s[1][0] != 0 && s[1][0] == s[1][1] && s[1][0] == s[1][2]) ||
(s[2][0] != 0 && s[2][0] == s[2][1] && s[2][0] == s[2][2]) ||
(s[0][0] != 0 && s[0][0] == s[1][0] && s[0][0] == s[2][0]) ||
(s[0][1] != 0 && s[0][1] == s[1][1] && s[0][1] == s[2][1]) ||
(s[0][2] != 0 && s[0][2] == s[1][2] && s[0][2] == s[2][2]) ||
(s[0][0] != 0 && s[0][0] == s[1][1] && s[0][0] == s[2][2]) ||
(s[0][2] != 0 && s[0][2] == s[1][1] && s[0][2] == s[2][0])) {
return true;
}
return false;
}
int maxValue(int h)
{
if (terminalTest())
return -(spaceNum() + 1);
if (h == 0)
return 0;
int v = -INF;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (s[i][j] == 0) {
s[i][j] = 1;
int t = minValue(h-1);
s[i][j] = 0;
if (t > v)
v = t;
}
}
}
return v;
}
int minValue(int h)
{
if (terminalTest()) {
return spaceNum() + 1;
}
if (h == 0)
return 0;
int v = INF;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (s[i][j] == 0) {
s[i][j] = 2;
int t = maxValue(h - 1);
s[i][j] = 0;
if (t < v)
v = t;
}
}
}
return v;
}
int main()
{
int n;
std::cin >> n;
while (n--) {
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
int t;
std::cin >> t;
s[i][j] = t;
}
}
std::cout << maxValue(spaceNum()) << std::endl;
}
}
剪枝算法 :
c++代码:
#include <iostream>
#include <algorithm>
#define INF 10
int s[4][4];
int minValue(int h, int alpha, int beta);
int spaceNum()
{
int n = 0;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (s[i][j] == 0)
++n;
}
}
return n;
}
bool terminalTest()
{
if ((s[0][0] != 0 && s[0][0] == s[0][1] && s[0][0] == s[0][2]) ||
(s[1][0] != 0 && s[1][0] == s[1][1] && s[1][0] == s[1][2]) ||
(s[2][0] != 0 && s[2][0] == s[2][1] && s[2][0] == s[2][2]) ||
(s[0][0] != 0 && s[0][0] == s[1][0] && s[0][0] == s[2][0]) ||
(s[0][1] != 0 && s[0][1] == s[1][1] && s[0][1] == s[2][1]) ||
(s[0][2] != 0 && s[0][2] == s[1][2] && s[0][2] == s[2][2]) ||
(s[0][0] != 0 && s[0][0] == s[1][1] && s[0][0] == s[2][2]) ||
(s[0][2] != 0 && s[0][2] == s[1][1] && s[0][2] == s[2][0])) {
return true;
}
return false;
}
int maxValue(int h, int alpha, int beta)
{
if (terminalTest())
return -(spaceNum() + 1);
if (h == 0)
return 0;
int v = -INF;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (s[i][j] == 0) {
s[i][j] = 1;
int t = minValue(h-1,alpha,beta);
s[i][j] = 0;
if (t > v) {
v = t;
if (v >= beta)
return v;
alpha = std::max(alpha, v);
}
}
}
}
return v;
}
int minValue(int h, int alpha, int beta)
{
if (terminalTest()) {
return spaceNum() + 1;
}
if (h == 0)
return 0;
int v = INF;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (s[i][j] == 0) {
s[i][j] = 2;
int t = maxValue(h - 1, alpha, beta);
s[i][j] = 0;
if (t < v) {
v = t;
if (v <= alpha)
return v;
beta = std::min(beta, v);
}
}
}
}
return v;
}
int main()
{
int n;
std::cin >> n;
while (n--) {
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
int t;
std::cin >> t;
s[i][j] = t;
}
}
std::cout << maxValue(spaceNum(),-INF,INF) << std::endl;
}
}
结果:
第一行为剪枝程序的运行结果,可见,剪枝后时间空间效率大幅提高。