접근

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

 

7682번: 틱택토

틱택토 게임은 두 명의 사람이 번갈아가며 말을 놓는 게임이다. 게임판은 3×3 격자판이며, 처음에는 비어 있다. 두 사람은 각각 X 또는 O 말을 번갈아가며 놓는데, 반드시 첫 번째 사람이 X를 놓고

www.acmicpc.net

탐색의 복잡함도 크지 않았고, 틱택토 게임판이 유효한 경우도 비교적 명확하여 쉽게 구현이 가능했다.

  1. X가 이기는 경우: X가 먼저 시작하고 마지막으로 놓고 이기기 때문에 X의 갯수가 1개 더 많아야 하고, O가 연속 3개가 있으면 안된다.
  2. O가 이기는 경우: O가 늦게 시작하고 마지막으로 놓고 이기기 때문에 X와 O의 갯수가 동일해야 하고, X가 연속 3개 있으면 안된다.
  3. 비기는 경우: X가 5개, O가 4개 있어야 하며 X와 O 모두 연속 3개 있으면 안된다.
  4. 그외에는 invalid

X가 이기는 경우, X가 연속 3개 있으면서 O가 연속 3개 있으면 안되기 때문에, 게임판을 탐색 및 체크하는 함수에서도 X가 연속 3개인지를 저장하는 변수와 O가 연속 3개인지를 저장하는 변수를 구분지어서 X와 O 둘 모두 연속 3개가 존재하는 경우와 각각 한가지만 연속 3개인 경우를 구분지어 리턴해주었다.

코드

#include <iostream>
#include <string>

using namespace std;

#define endl '\n'

char MAP[3][3];
int xnum, onum;

// MAP을 탐색하여 연속3개 있는 문자를 체크하는 함수
int check() {
    int x = 0;
    int o = 0;
    for (int i = 0; i < 3; i++) {
        if (MAP[i][0] == MAP[i][1] && MAP[i][1] == MAP[i][2]) {
            if (MAP[i][0] == 'X') x = 1;
            if (MAP[i][0] == 'O') o = 1;
        };
        if (MAP[0][i] == MAP[1][i] && MAP[1][i] == MAP[2][i]) {
            if (MAP[0][i] == 'X') x = 1;
            if (MAP[0][i] == 'O') o = 1;
        };
    }
    if (MAP[0][0] == MAP[1][1] && MAP[1][1] == MAP[2][2]) {
        if (MAP[1][1] == 'X') x = 1;
        if (MAP[1][1] == 'O') o = 1;
    };
    if (MAP[0][2] == MAP[1][1] && MAP[1][1] == MAP[2][0]) {
        if (MAP[1][1] == 'X') x = 1;
        if (MAP[1][1] == 'O') o = 1;
    };
    if (x == 1 && o == 1) {
        // X와 O가 연속 3개 있는 경우
        return 3;
    } else if (x == 1) {
        // X만 연속 3개 있는 경우
        return 1;
    } else if (o == 1) {
        // Y만 연속 3개 있는 경우
        return 2;
    } else {
        // 비기는 경우
        return 0;
    }
}

int main(int argc, char** argv) {
    // freopen 주석 처리
    freopen("input.txt", "r", stdin);

    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    while (1) {
        int valid = 0;
        string in;
        cin >> in;
        if (in == "end") break;
        int index = 0;
        xnum = 0;
        onum = 0;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                MAP[i][j] = in[index++];
                switch (MAP[i][j]) {
                    case 'O':
                        onum++;
                        break;
                    case 'X':
                        xnum++;
                        break;
                }
            }
        }
        if (xnum - onum == 1 && check() == 1) {
            // X가 이기는 경우
            valid = 1;
        } else if (xnum - onum == 0 && check() == 2) {
            // O가 이기는 경우
            valid = 1;
        } else if (xnum == 5 && onum == 4 && check() == 0) {
            // 비기는 경우
            valid = 1;
        }
        if (valid) {
            cout << "valid" << endl;
        } else {
            cout << "invalid" << endl;
        }
    }

    return 0;
}

더 생각해 볼 것?

...

코드나 내용 관련 조언, 부족한 점 및 질문 언제든 환영합니다!

반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기