1 条题解

  • 0
    @ 2025-10-31 21:57:27

    这道题的正确输出是这样的:

    131184 4.61
    77904 3.93
    46080
    51.41% 30.53% 18.06%
    

    下面给个参考代码:

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    long long a[3][3] = {0}; // 使用0-based索引,初始化为0[1,6](@ref)
    long long win[3] = {0};  // win[0]:平局, win[1]:先手胜, win[2]:后手胜
    double step1 = 0, step2 = 0; // 用于累计先手和后手的获胜总步数
    
    // 修正后的胜负判断函数[1,6](@ref)
    int check() {
        // 检查行
        for (int i = 0; i < 3; i++) {
            if (a[i][0] != 0 && a[i][0] == a[i][1] && a[i][1] == a[i][2]) {
                return a[i][0];
            }
        }
        // 检查列
        for (int j = 0; j < 3; j++) {
            if (a[0][j] != 0 && a[0][j] == a[1][j] && a[1][j] == a[2][j]) {
                return a[0][j];
            }
        }
        // 检查主对角线
        if (a[0][0] != 0 && a[0][0] == a[1][1] && a[1][1] == a[2][2]) {
            return a[0][0];
        }
        // 检查副对角线
        if (a[0][2] != 0 && a[0][2] == a[1][1] && a[1][1] == a[2][0]) {
            return a[0][2];
        }
        return 0; // 尚无胜者
    }
    
    // 判断棋盘是否已满(平局条件)[6](@ref)
    bool isBoardFull() {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (a[i][j] == 0) return false;
            }
        }
        return true;
    }
    
    // 深度优先搜索函数
    void dfs(int currentPlayer, int stepsPlayer1, int stepsPlayer2) {
        int result = check();
        // 先检查是否已有胜者[3](@ref)
        if (result != 0) {
            win[result]++;
            if (result == 1) {
                step1 += stepsPlayer1;
            } else if (result == 2) {
                step2 += stepsPlayer2;
            }
            return;
        }
        // 再检查是否平局[6](@ref)
        if (isBoardFull()) {
            win[0]++;
            return;
        }
    
        // 遍历所有空位
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (a[i][j] == 0) {
                    a[i][j] = currentPlayer;
                    if (currentPlayer == 1) {
                        dfs(2, stepsPlayer1 + 1, stepsPlayer2); // 轮到后手
                    } else {
                        dfs(1, stepsPlayer1, stepsPlayer2 + 1); // 轮回到先手
                    }
                    a[i][j] = 0; // 回溯,撤销落子
                }
            }
        }
    }
    
    int main() {
        memset(a, 0, sizeof(a));
        dfs(1, 0, 0); // 从先手(玩家1)开始
    
        long long total = win[0] + win[1] + win[2];
        // 计算平均获胜步数,避免除零错误[4](@ref)
        double avg_steps_first = (win[1] > 0) ? (step1 / win[1]) : 0.0;
        double avg_steps_second = (win[2] > 0) ? (step2 / win[2]) : 0.0;
    
        printf("%lld %.2lf\n", win[1], avg_steps_first);
        printf("%lld %.2lf\n", win[2], avg_steps_second);
        printf("%lld\n", win[0]);
    
        printf("%.2lf%% ", 100.0 * win[1] / total);
        printf("%.2lf%% ", 100.0 * win[2] / total);
        printf("%.2lf%%", 100.0 * win[0] / total);
        return 0;
    }
    

    信息

    ID
    5
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    提交数
    6
    已通过
    1
    上传者