题解:P13281 [GCJ 2013 Qualification] Tic-Tac-Toe-Tomek

· · 题解

“题前”分析

“磨你题”。

最多模拟不超过十万次,加上一些杂七杂八的复杂度,模拟一定不会超时。

记住,数据范围很小且题目中有“规则怪谈”时(它给的规则大多很奇怪),这题就一定是模拟题

思路

规则给的很清楚:判断横竖斜(行、列、对角线)是否有四个同样的或三个同样加个 T(细节:三个同样的不能是 .)。如果没有人获胜,且盘面没有被填满(存在 .),则游戏没有结束,否则输出平局

思路解析

读入:

读入不必说,注意一点,你从哪开始读入就从哪枚举(string 字符串从 0 枚举)。

判断空格:

只要发现有一个字符是 .,就说明棋盘还没满,后面可能还要接着下。但我们不能确定是否已经下完,万一下完了,对手被秒了,结果你就输出没下完,活该过不了。所以最好使用一个布尔变量,标记为

检查谁赢了:

分三部分查:

这边注意一下:如果是 X3 个再加一个 T,会有两种情况,别漏了。

只要任何一个方向满足条件,就可以直接输出了。但我建议定义两个布尔变量,如果 X 方获胜把对应的布尔变量增加(O 方获胜同理)。

输出结果:

按照优先级输出(X 赢和 O 赢处于同一优先级,但不可能出现二人都赢的情况,所以为了方便判断,可以将任意一个先判断):

#include <iostream>
using namespace std;
int main() {
    int T;
    cin >> T;
    for (int t = 1; t <= T; ++t) {
        char b[5][5];
        bool full = 1, x = 0, o = 0;
        for (int i = 0; i < 4; ++i) cin >> b[i];

        for (int i = 0; i < 4; ++i) {
            for (int j = 0; j < 4; ++j) {
                if (b[i][j] == '.') full = 0;
            }
        }

        for (int i = 0; i < 4; ++i) {
            int cx = 0, co = 0, ct = 0;
            for (int j = 0; j < 4; ++j) {
                if (b[i][j] == 'X') cx++;
                else if (b[i][j] == 'O') co++;
                else if (b[i][j] == 'T') ct++;
            }
            if (cx == 4 || (cx == 3 && ct == 1)) x = 1;
            if (co == 4 || (co == 3 && ct == 1)) o = 1;
        }

        for (int j = 0; j < 4; ++j) {
            int cx = 0, co = 0, ct = 0;
            for (int i = 0; i < 4; ++i) {
                if (b[i][j] == 'X') cx++;
                else if (b[i][j] == 'O') co++;
                else if (b[i][j] == 'T') ct++;
            }
            if (cx == 4 || (cx == 3 && ct == 1)) x = 1;
            if (co == 4 || (co == 3 && ct == 1)) o = 1;
        }

        int cx = 0, co = 0, ct = 0;
        for (int i = 0; i < 4; ++i) {
            if (b[i][i] == 'X') cx++;
            else if (b[i][i] == 'O') co++;
            else if (b[i][i] == 'T') ct++;
        }
        if (cx == 4 || (cx == 3 && ct == 1)) x = 1;
        if (co == 4 || (co == 3 && ct == 1)) o = 1;

        cx = 0, co = 0, ct = 0;
        for (int i = 0; i < 4; ++i) {
            if (b[i][3 - i] == 'X') cx++;
            else if (b[i][3 - i] == 'O') co++;
            else if (b[i][3 - i] == 'T') ct++;
        }
        if (cx == 4 || (cx == 3 && ct == 1)) x = 1;
        if (co == 4 || (co == 3 && ct == 1)) o = 1;

        cout << "Case #" << t << ": ";
        if (x) cout << "X won";
        else if (o) cout << "O won";
        else if (full) cout << "Draw";
        else cout << "Game has not completed";
        cout << endl;
    }
    return 0;
}