問題描述
試題編號: | 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;
}
}
結果:
第一行爲剪枝程序的運行結果,可見,剪枝後時間空間效率大幅提高。