Blog / Algorithm / 백준 7682번 틱택토 — 구현 C++ 풀이
Algorithm

백준 7682번 틱택토 — 구현 C++ 풀이

백준 7682번 틱택토 풀이. X와 O 개수 조건과 8가지 승리 조건을 조합해 최종 보드 상태가 유효한 게임 결과인지 판별하는 구현 C++ 코드와 풀이 과정을 정리한다.

문제

BOJ 7682 - 틱택토

3×3 틱택토 보드의 최종 상태가 주어졌을 때, 그것이 유효한 게임 결과인지 판별하는 문제다.

핵심 아이디어

  1. X가 선공이므로 항상 X 개수 >= O 개수여야 한다.
  2. X와 O의 차이는 최대 1이다.
  3. 승리 조건 8가지(가로 3, 세로 3, 대각선 2)를 미리 테이블로 정의한다.
  4. 다음 케이스들을 구분하여 유효성을 판별한다:
    • X만 승리: O는 X보다 적어야 한다 (X가 마지막 수)
    • O만 승리: X와 O 개수가 같아야 한다 (O가 마지막 수)
    • 둘 다 승리: 불가능
    • 아무도 안 이김: 빈 칸이 0이어야 유효 (무승부)

풀이

#include <iostream>
#include <string>

using namespace std;

int t[8][9] = {
    {1,1,1, 0,0,0, 0,0,0},  // 가로 1행
    {0,0,0, 1,1,1, 0,0,0},  // 가로 2행
    {0,0,0, 0,0,0, 1,1,1},  // 가로 3행
    {1,0,0, 1,0,0, 1,0,0},  // 세로 1열
    {0,1,0, 0,1,0, 0,1,0},  // 세로 2열
    {0,0,1, 0,0,1, 0,0,1},  // 세로 3열
    {1,0,0, 0,1,0, 0,0,1},  // 대각선 ↘
    {0,0,1, 0,1,0, 1,0,0}   // 대각선 ↙
};

bool check_winner(string& board, char type) {
    for (int i = 0; i < 8; i++) {
        int w = 0;
        for (int j = 0; j < 9; j++) {
            if (t[i][j] && type == board[j]) w++;
        }
        if (w == 3) return true;
    }
    return false;
}

int main() {
    while (true) {
        int x, o, blank;
        x = o = blank = 0;
        string board;

        cin >> board;
        if (board == "end") break;

        for (int i = 0; i < 9; i++) {
            if (board[i] == 'X') x++;
            else if (board[i] == 'O') o++;
            else blank++;
        }

        // O가 X보다 많을 수 없다
        if (o > x) { cout << "invalid" << endl; continue; }
        // 차이는 1 이하
        if (abs(x - o) > 1) { cout << "invalid" << endl; continue; }

        bool x_win = check_winner(board, 'X');
        bool o_win = check_winner(board, 'O');

        if (o_win && !x_win) {
            cout << (o < x ? "invalid" : "valid") << endl;
        } else if (x_win && !o_win) {
            cout << (o >= x ? "invalid" : "valid") << endl;
        } else if (o_win && x_win) {
            cout << "invalid" << endl;
        } else {
            // 아무도 안 이겼으면 보드가 꽉 차야 유효
            cout << (blank == 0 ? "valid" : "invalid") << endl;
        }
    }

    return 0;
}

주요 포인트

  • 승리 패턴을 2D 배열로 미리 정의하면 코드가 깔끔해진다.
  • X가 이겼을 때 o >= x이면 O가 추가로 수를 둔 것이므로 invalid다.
  • O가 이겼을 때 o < x이면 X가 추가로 수를 둔 것이므로 invalid다.

복잡도

  • 시간: O(T × 8 × 9) — T: 테스트 케이스 수
  • 공간: O(1)

모든 예외 케이스를 빠짐없이 처리해야 하는, 꼼꼼한 구현이 필요한 문제다.

댓글

블로그 목록으로
ACHIEVEMENT UNLOCKED
LOADING...
SCORE 000000
HITS
0