[CF3C]Tic-tac-toe 题解

[CF3C]Tic-tac-toe 题解

题目地址:Codeforces:Problem – 3C – Codeforces、洛谷:CF3C Tic-tac-toe – 洛谷 | 计算机科学教育新生态

题目描述

Certainly, everyone is familiar with tic-tac-toe game. The rules are very simple indeed. Two players take turns marking the cells in a 3 × 3 grid (one player always draws crosses, the other — noughts). The player who succeeds first in placing three of his marks in a horizontal, vertical or diagonal line wins, and the game is finished. The player who draws crosses goes first. If the grid is filled, but neither Xs, nor 0s form the required line, a draw is announced.

You are given a 3 × 3 grid, each grid cell is empty, or occupied by a cross or a nought. You have to find the player (first or second), whose turn is next, or print one of the verdicts below:

  • illegal — if the given board layout can’t appear during a valid game;
  • the first player won — if in the given board layout the first player has just won;
  • the second player won — if in the given board layout the second player has just won;
  • draw — if the given board layout has just let to a draw.

题意简述

给一个井字棋(三子棋)的局面,请判断该局面的状态,状态有以下几种:

  • 下一步X玩家下棋
  • 下一步O玩家下棋
  • 非法状态(正常游戏过程中不会出现的局面)
  • X玩家获胜
  • O玩家获胜
  • 平局

井字棋玩法请百度。

输入输出格式

输入格式:
The input consists of three lines, each of the lines contains characters “.”, “X” or “0” (a period, a capital letter X, or a digit zero).

输出格式:
Print one of the six verdicts: first, second, illegal, the first player won, the second player won or draw.

输入输出样例

输入样例#1:

X0X
.0.
.X.

输出样例#1:

second

题解

大模拟题,细节和分类特别多。分状态讨论符合的情况。

下一步X下棋,仅出现于合法且无人获胜的局面中,特征是局面中X和O的数量相同。
下一步O下棋,仅出现于合法且无人获胜的局面中,特征是局面中X比O的数量多1。
非法状态,有以下几类:X与O的数量的关系既不是相同也不是X比O多1;X获胜之后O仍然下了一步棋(X获胜之后X与O数量相同);O获胜之后X仍然下了一步棋(O获胜之后X比O数量多1)。
X获胜,合法局面中X棋子占据了某一行、列或正副对角线。
O获胜,合法局面中O棋子占据了某一行、列或正副对角线。
平局,合法局面,无人获胜,且棋盘中没有空位。

调试的时候平均一个submission过一个测试点,果然还是我太菜了。

代码

// Code by KSkun, 2019/6
#include <cstdio>

char a[5][5];

int main() {
    scanf("%s%s%s", a[1] + 1, a[2] + 1, a[3] + 1);
    int cntx = 0, cnto = 0;
    bool hasdot = false;
    for(int i = 1; i <= 3; i++) {
        for(int j = 1; j <= 3; j++) {
            if(a[i][j] == 'X') cntx++;
            if(a[i][j] == '0') cnto++;
            if(a[i][j] == '.') hasdot = true;
        }
    }
    if(cntx != cnto && cntx != cnto + 1) {
        puts("illegal"); return 0;
    }
    bool fw = false, sw = false;
    for(int i = 1; i <= 3; i++) {
        if(a[i][1] == a[i][2] && a[i][2] == a[i][3]) {
            if(a[i][1] == 'X') fw = true;
            else if(a[i][1] == '0') sw = true;
        }
    }
    for(int i = 1; i <= 3; i++) {
        if(a[1][i] == a[2][i] && a[2][i] == a[3][i]) {
            if(a[1][i] == 'X') fw = true;
            else if(a[1][i] == '0') sw = true;
        }
    }
    if(a[1][1] == a[2][2] && a[2][2] == a[3][3]) {
        if(a[1][1] == 'X') fw = true;
        else if(a[1][1] == '0') sw = true;
    }
    if(a[1][3] == a[2][2] && a[2][2] == a[3][1]) {
        if(a[1][3] == 'X') fw = true;
        else if(a[1][3] == '0') sw = true;
    }
    if(fw && sw) puts("illegal");
    else if(fw && cntx != cnto + 1) puts("illegal");
    else if(sw && cntx != cnto) puts("illegal");
    else if(fw) puts("the first player won");
    else if(sw) puts("the second player won");
    else if(!hasdot) puts("draw");
    else if(cntx == cnto) puts("first");
    else if(cntx == cnto + 1) puts("second");
    return 0;
}


发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据