알고리즘/백준

백준_7682 : 틱택토 - C++

맏리믓 2023. 8. 4. 20:09

문제

https://www.acmicpc.net/problem/7682

 

7682번: 틱택토

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 줄은 9개의 문자를 포함하며, 'X', 'O', '.' 중 하나이다. '.'은 빈칸을 의미하며, 9개의 문자는 게임판에서 제일 윗 줄 왼쪽부터의 순서이다. 입

www.acmicpc.net


문제 해석

- 입력값으로 3*3 의 게임 판에 O, X 를 표기하여 주어진다.

- 주어진 게임판의 상황이 나올 수 있는 상황인지, 끝난 상황인지 확인 하는 문제이다.

- 예를 들어 "X.OO..X.." 는 나올 수는 있는 상황이지만 게임의 최동 모습이 아니기 때문에 "invalid" 이다.


문제 풀이

- 게임이 정상적으로 끝났다면 다음 상황 중 하나이다.

 . O 를 표기 한 사람의 승리

 . X 를 표기 한 사람의 승리

 . 비김

 

- 각 상황을 더 자세히 분석 하면 다음과 같다.

 . O 를 표기 한 사람의 승리

   - O 가 가로, 세로, 대각 으로 3개가 연속해 있어야 한다. 

   - X 가 먼저 시작 하기 때문에 O 와 X 의 개수가 동일 해야 한다.

   - X 와 O 가 동시에 승리 할 수는 없다(X 도 3개가 연속 된게 있으면 안된다.)

 . X 를 표기 한 사람의 승리

   - 위 상황과 정확히 반대 이면 된다.

   - 다만 X 가 먼저 두기 때문에 승리 시 X 가 O 보다 하나 많아야 한다.

 . 비김

   - 모든 판이 가득 차 있어야 하며 X 가 O 보다 하나 많아야 한다

   - 즉 X 가 5개, O 가 4개 여야 한다.

 

- 위 상황을 제외 한 나머지 상황은 나올 수 없는 상태 이거나 게임이 아직 끝나지 않은 상태이다.


코드

#include <iostream>
using namespace std;

string input = "";
char board[3][3];
int X_cnt, O_cnt;

bool Xwin(){
    bool result = false;
    //가로
    for(int i = 0; i < 3; i++){
        if( (board[i][0] == 'X') && (board[i][0] == board[i][1]) && (board[i][1] == board[i][2])){
            result = true;
        }
    }

    //세로
    for(int i = 0; i < 3; i++){
        if( (board[0][i] == 'X') && (board[0][i] == board[1][i]) && (board[1][i] == board[2][i])){
            result = true;
        }
    }

    //대각
    if( (board[0][0] == 'X') && (board[0][0] == board[1][1]) && (board[1][1] == board[2][2])){
        result = true;
    }

    //반대 대각
    if( (board[0][2] == 'X') && (board[0][2] == board[1][1]) && (board[1][1] == board[2][0])){
        result = true;
    }
    
    return result;
}

bool Owin(){
    bool result = false;
    //가로    
    for(int i = 0; i < 3; i++){
        if( (board[i][0] == 'O') && (board[i][0] == board[i][1]) && (board[i][1] == board[i][2])){
            result = true;
        }
    }

    //세로
    for(int i = 0; i < 3; i++){
        if( (board[0][i] == 'O') && (board[0][i] == board[1][i]) && (board[1][i] == board[2][i])){
            result = true;
        }
    }

    //대각
    if( (board[0][0] == 'O') && (board[0][0] == board[1][1]) && (board[1][1] == board[2][2])){
        result = true;
    }

    //반대 대각
    if( (board[0][2] == 'O') && (board[0][2] == board[1][1]) && (board[1][1] == board[2][0])){
        result = true;
    }
    
    return result;
}

void solution(){
    while(true){
        cin >> input;
        X_cnt = 0; O_cnt = 0;
        if(input != "end"){
            for(int i = 0; i < 9; i++){
                board[i/3][i%3] = input[i];
                if(input[i] == 'O'){
                    O_cnt += 1;
                } else if(input[i] == 'X'){
                    X_cnt += 1;
                }
            }

            bool O = Owin();
            bool X = Xwin();

            if(X && !O && (X_cnt - O_cnt == 1)){
                cout << "valid\n";
            } else if(!X && O && (X_cnt - O_cnt == 0)){
                cout << "valid\n";
            } else if(!X && !O && X_cnt == 5 && O_cnt == 4){
                cout << "valid\n";
            } else {
                cout << "invalid\n";
            }
        } else {
            break;
        }
    }
}


int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    solution();
}