CCF 棋局評估
問題描述
試題編號: | 201803-4 |
試題名稱: | 棋局評估 |
時間限制: | 1.0秒 |
記憶體限制: | 256.0MB |
問題描述: |
問題描述 愛麗絲和鮑勃正在玩井字棋遊戲。 輸入格式 輸入的第一行包含一個正整數T,表示資料的組數。 輸出格式 對於每組資料,輸出一行一個整數,表示當前局面的得分。 樣例輸入 3 樣例輸出 3 樣例說明 第一組資料: 資料規模和約定 對於所有評測用例,1≤ |
50分的程式碼......不知道怎麼改進
我的想法是,每次進入DFS是判斷當前局勢是否可以結束遊戲,可以則優化微型和馬克西,如不能,則進行此次的最優下法,方法如下:判斷是否有哪一步可以讓自己獲勝,如沒有,則判斷是否接下來一步對手能獲勝,有的話則封堵他,如進入這兩個判斷語句,則執行都回,因為是最優解,必須執行,如果都不滿足,則遍歷剩餘0
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#define MAX_SIZE 1005
#define INF 10
using namespace std;
int matrix[4][4];
int n, node_i, node_j;
int mini = INF, maxi = -INF;
int nextItem(int index)
{
return index == 1 ? 2 : 1;
}
bool check_x_y(int index)
{
int num[3] = {0}, loc = 0;
for (int j = 1; j <= 3; j++)
{
//判斷行
num[0] = num[1] = num[2] = 0;
loc = 0;
switch (matrix[j][1])
{
case 0:
loc = 1;
num[0]++;
break;
case 1:
num[1]++;
break;
case 2:
num[2]++;
break;
}
switch (matrix[j][2])
{
case 0:
loc = 2;
num[0]++;
break;
case 1:
num[1]++;
break;
case 2:
num[2]++;
break;
}
switch (matrix[j][3])
{
case 0:
loc = 3;
num[0]++;
break;
case 1:
num[1]++;
break;
case 2:
num[2]++;
break;
}
if (num[0] == 1)
{
if (num[index] == 2)
{
node_i = j;
node_j = loc;
return 1;
}
}
//判斷列
num[0] = num[1] = num[2] = 0;
loc = 0;
switch (matrix[1][j])
{
case 0:
loc = 1;
num[0]++;
break;
case 1:
num[1]++;
break;
case 2:
num[2]++;
break;
}
switch (matrix[2][j])
{
case 0:
loc = 2;
num[0]++;
break;
case 1:
num[1]++;
break;
case 2:
num[2]++;
break;
}
switch (matrix[3][j])
{
case 0:
loc = 3;
num[0]++;
break;
case 1:
num[1]++;
break;
case 2:
num[2]++;
break;
}
if (num[0] == 1)
{
if (num[index] == 2)
{
node_i = loc;
node_j = j;
return 1;
}
}
}
//判斷正斜
num[0] = num[1] = num[2] = 0;
loc = 0;
switch (matrix[1][1])
{
case 0:
loc = 1;
num[0]++;
break;
case 1:
num[1]++;
break;
case 2:
num[2]++;
break;
}
switch (matrix[2][2])
{
case 0:
loc = 2;
num[0]++;
break;
case 1:
num[1]++;
break;
case 2:
num[2]++;
break;
}
switch (matrix[3][3])
{
case 0:
loc = 3;
num[0]++;
break;
case 1:
num[1]++;
break;
case 2:
num[2]++;
break;
}
if (num[0] == 1)
{
if (num[index] == 2)
{
node_i = loc;
node_j = loc;
return 1;
}
}
//判斷反斜
num[0] = num[1] = num[2] = 0;
loc = 0;
switch (matrix[1][3])
{
case 0:
loc = 1;
num[0]++;
break;
case 1:
num[1]++;
break;
case 2:
num[2]++;
break;
}
switch (matrix[2][2])
{
case 0:
loc = 2;
num[0]++;
break;
case 1:
num[1]++;
break;
case 2:
num[2]++;
break;
}
switch (matrix[3][1])
{
case 0:
loc = 3;
num[0]++;
break;
case 1:
num[1]++;
break;
case 2:
num[2]++;
break;
}
if (num[0] == 1)
{
if (num[index] == 2)
{
node_i = loc;
node_j = 4 - loc;
return 1;
}
}
return 0;
}
int getWhite()
{
int num = 0;
for (int i = 1; i <= 3; i++)
{
for (int j = 1; j <= 3; j++)
{
if (matrix[i][j] == 0)
{
num++;
}
}
}
return num;
}
int win()
{
for (int i = 1; i <= 3; i++)
{
if (matrix[i][1] == matrix[i][2] && matrix[i][2] == matrix[i][3] && matrix[i][2] != 0)
{
return matrix[i][2];
}
if (matrix[1][i] == matrix[2][i] && matrix[2][i] == matrix[3][i] && matrix[2][i] != 0)
{
return matrix[2][i];
}
}
if (matrix[1][1] == matrix[2][2] && matrix[2][2] == matrix[3][3] && matrix[2][2] != 0)
{
return matrix[2][2];
}
if (matrix[1][3] == matrix[2][2] && matrix[2][2] == matrix[3][1] && matrix[2][2] != 0)
{
return matrix[2][2];
}
return 0;
}
bool checkGameOver()
{
int white = getWhite(), res = win();
if (res != 0)
{
if (res == 1)
{
// cout << "本次遊戲結束. 1 勝利,空白個數:" << white << endl;
maxi = max(maxi, white + 1);
}
else
{
// cout << "本次遊戲結束. 2 勝利,空白個數:" << white << endl;
mini = min(mini, -white - 1);
}
// for (int i = 1; i <= 3; i++)
// {
// for (int j = 1; j <= 3; j++)
// {
// cout << matrix[i][j];
// }
// cout << endl;
// }
return true;
}
return false;
}
void dfs(int index)
{
//判斷是否結束
if (checkGameOver())
{
return;
}
//檢測能否有讓自己勝利的步局
if (check_x_y(index) == 1)
{
// cout << index << "發現可勝利位置,落子在(" << node_i << "," << node_j << ")" << endl;
int a = node_i, b = node_j;
matrix[a][b] = index;
dfs(nextItem(index));
matrix[a][b] = 0;
return;
}
//檢測能否有讓對手下一步勝利的步局
if (check_x_y(nextItem(index)) == 1)
{
// cout << index << "發現對手有可勝位置,落子在(" << node_i << "," << node_j << ")" << endl;
int a = node_i, b = node_j;
matrix[a][b] = index;
dfs(nextItem(index));
matrix[a][b] = 0;
return;
}
// 遍歷空白
for (int i = 1; i <= 3; i++)
{
for (int j = 1; j <= 3; j++)
{
if (matrix[i][j] == 0)
{
// cout << index << "落子在(" << i << "," << j << ")" << endl;
matrix[i][j] = index;
dfs(nextItem(index));
matrix[i][j] = 0;
}
}
}
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
cin >> n;
for (int i = 1; i <= n; i++)
{
mini = INF, maxi = -INF;
for (int j = 1; j <= 3; j++)
{
cin >> matrix[j][1] >> matrix[j][2] >> matrix[j][3];
}
//判斷空
bool nullFlag = true;
for (int j = 1; j <= 3; j++)
{
if (matrix[j][1] != 0 || matrix[j][2] != 0 || matrix[j][3] != 0)
{
nullFlag = false;
break;
}
}
if (nullFlag)
{
cout << 0 << endl;
continue;
}
//dfs
dfs(1);
if (maxi != -INF)
{
cout << maxi << endl;
}
else if (mini != INF)
{
cout << mini << endl;
}
else
{
cout << 0 << endl;
}
}
return 0;
}