CCF CSP 竞赛试题——棋局评估(201803-4)

  • 大力出奇迹
  • 两者最优下棋策略,体现为“在任意空位下子,对所有可能的结果,取最好的”。
#include <iostream>
#include <vector>
#include <cctype>
#include <string>
#include <stdio.h>
using namespace std;

#define N 3

bool AliceWin(const vector<vector<int> >& grid) {
    for (int i = 0; i < N; ++i) {
        if (grid[i][0] + grid[i][1] + grid[i][2] == 3 && (grid[i][0] ^ grid[i][1] ^ grid[i][2]) == 1)
            return true;
        if (grid[0][i] + grid[1][i] + grid[2][i] == 3 && (grid[0][i] ^ grid[1][i] ^ grid[2][i]) == 1)
            return true;
    }
    if (grid[0][0] + grid[1][1] + grid[2][2] == 3 && (grid[0][0] ^ grid[1][1] ^ grid[2][2]) == 1)
        return true;
    if (grid[0][2] + grid[1][1] + grid[2][0] == 3 && (grid[0][2] ^ grid[1][1] ^ grid[2][0]) == 1)
        return true;
    return false;
}

bool BobWin(const vector<vector<int> >& grid) {
    for (int i = 0; i < N; ++i) {
        if (grid[i][0] + grid[i][1] + grid[i][2] == 6) return true;
        if (grid[0][i] + grid[1][i] + grid[2][i] == 6) return true;
    }
    if (grid[0][0] + grid[1][1] + grid[2][2] == 6) return true;
    if (grid[0][2] + grid[1][1] + grid[2][0] == 6) return true;
    return false;
}

int count(const vector<vector<int> >& grid) {
    int cnt = 0;
    for (int i = 0; i < N; ++i)
        for (int j = 0; j < N; ++j)
            if (grid[i][j] == 0)
                ++cnt;
    return cnt;
}

int dfs(vector<vector<int> >& grid, int x = 1) {
    if (x == 1 && BobWin(grid)) return -1 - count(grid); // 下子前,先判断前一个人是否已经赢了
    if (x == 2 && AliceWin(grid)) return 1 + count(grid);
    if (x == 2 && count(grid) == 0) return 0;
    int res = (x == 1 ? -12 : 12);
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N; ++j) if (grid[i][j] == 0) { // 任意取一个空位下子
            grid[i][j] = x;
            if (x == 1)
                res = max(res, dfs(grid, 2)); // 对于Alice,要取可能的最高分
            else
                res = min(res, dfs(grid, 1)); // 对于Bob,要取可能的最低分
            grid[i][j] = 0;
        }
    }
    return res;
}

int main() {
    int T;
    cin >> T;
    while (T--) {
        vector<vector<int> > grid(N, vector<int>(N));
        for (int i = 0; i < N; ++i)
            for (int j = 0; j < N; ++j)
                cin >> grid[i][j];
        cout << dfs(grid) << endl;
    }
    return 0;
}
发布了33 篇原创文章 · 获赞 4 · 访问量 8745

猜你喜欢

转载自blog.csdn.net/Touchig/article/details/102800621