프로그래밍 공부
작성일
2024. 3. 21. 16:50
작성자
WDmil
728x90

문제 설명

틱택토는 두 사람이 하는 게임으로 처음에 3x3의 빈칸으로 이루어진 게임판에 선공이 "O", 후공이 "X"를 번갈아가면서 빈칸에 표시하는 게임입니다. 가로, 세로, 대각선으로 3개가 같은 표시가 만들어지면 같은 표시를 만든 사람이 승리하고 게임이 종료되며 9칸이 모두 차서 더 이상 표시를 할 수 없는 경우에는 무승부로 게임이 종료됩니다.

 

할 일이 없어 한가한 머쓱이는 두 사람이 하는 게임인 틱택토를 다음과 같이 혼자서 하려고 합니다.

 

혼자서 선공과 후공을 둘 다 맡는다.

틱택토 게임을 시작한 후 "O" "X"를 혼자서 번갈아 가면서 표시를 하면서 진행한다.

틱택토는 단순한 규칙으로 게임이 금방 끝나기에 머쓱이는 한 게임이 종료되면 다시 3x3 빈칸을 그린 뒤 다시 게임을 반복했습니다. 그렇게 틱택토 수 십 판을 했더니 머쓱이는 게임 도중에 다음과 같이 규칙을 어기는 실수를 했을 수도 있습니다.

 

"O"를 표시할 차례인데 "X"를 표시하거나 반대로 "X"를 표시할 차례인데 "O"를 표시한다.

선공이나 후공이 승리해서 게임이 종료되었음에도 그 게임을 진행한다.

게임 도중 게임판을 본 어느 순간 머쓱이는 본인이 실수를 했는지 의문이 생겼습니다. 혼자서 틱택토를 했기에 게임하는 과정을 지켜본 사람이 없어 이를 알 수는 없습니다. 그러나 게임판만 봤을 때 실제로 틱택토 규칙을 지켜서 진행했을 때 나올 수 있는 상황인지는 판단할 수 있을 것 같고 문제가 없다면 게임을 이어서 하려고 합니다.

 

머쓱이가 혼자서 게임을 진행하다 의문이 생긴 틱택토 게임판의 정보를 담고 있는 문자열 배열 board가 매개변수로 주어질 때, 이 게임판이 규칙을 지켜서 틱택토를 진행했을 때 나올 수 있는 게임 상황이면 1을 아니라면 0 return 하는 solution 함수를 작성해 주세요.

 

제한사항

  • board의 길이 = board[i]의 길이 = 3
  • board의 원소는 모두 "O", "X", "."으로만 이루어져 있습니다.
  • board[i][j]는 i + 1행 j + 1열에 해당하는 칸의 상태를 나타냅니다.
  • "."은 빈칸을, "O"와 "X"는 해당 문자로 칸이 표시되어 있다는 의미입니다.

입출력 예

board result
["O.X", ".O.", "..X"] 1
["OOO", "...", "XXX"] 0
["...", ".X.", "..."] 0
["...", "...", "..."] 1

문제 해설

 

문제가 매우 귀찮게 짜여져 있다.

조건항에 대하여 가장 최대의 효율을 가져오는 조건을 찾아야 하는데,

 

조건은 다음과 같다.

O가 이겼을 경우, O의 개수 - X의 개수가 1이 되어야 한다.

X가 이겼을 경우, O의 개수 - X의 개수가 0이 되어야 한다.

O와 X는 동시에 이길 수 없다.

O의 개수 - X의 개수는 항상 0보다 같거나 커야하고, 1과 같거나 작아야한다.

 

이 조건을 찾는 방식이 코딩테스트와는 큰 연관이 없고, 그냥 틱택토의 개념에 대해서 이해를 요구한다.

코딩테스트 가 아니라 그냥 문제풀이 라고 생각


첫 번째 시도

#include <string>
#include <vector>

using namespace std;

void ChackToBingo(const int& input, int& X, int& O)
{
    if (input == 3) X++;
    else if (input == -3) O++;
}

int solution(vector<string> board) {

    int count = 0;
    int wino = 0, winx = 0;
    vector<vector<int>> intBoard;
    for (auto& def : board) {
        intBoard.push_back({});

        for (auto& def1 : def)
            if (def1 == 'O') intBoard.back().push_back(1);
            else if (def1 == 'X') intBoard.back().push_back(-1);
            else intBoard.back().push_back(0);
    }

    int chackLX = 0;
    int chackRX = 0;
    for (int i = 0; i < 3; i++)
    {
        int chackR = 0;
        int chackD = 0;
        for (int j = 0; j < 3; j++) {
            chackR += intBoard[i][j];
            chackD += intBoard[j][i];
            count += intBoard[i][j];
        }
        ChackToBingo(chackR, wino, winx);
        chackLX += intBoard[i][i];
        chackRX += intBoard[2 - i][2 - i];
    }
    ChackToBingo(chackLX, wino, winx);
    if (wino + winx > 1 || count != 0 || wino < winx) return 0;
    return 1;
}

실패

 

객체의 조건항을 제대로 이해하지 못했고, 오류또한 몃가지 있었다. 빙고 확인에 대해 LX RX, R D를 전부 확인헀어야 하는데, 확인을 한개씩만 하였고, 조건도 정상적으로 달지 못했다.


두 번째 시도

#include <string>
#include <vector>

using namespace std;

void ChackToBingo(const int& input, int& X, int& O)
{
    if (input == 3) X++;
    else if (input == -3) O++;
}

int solution(vector<string> board) {

    int count = 0;
    int wino = 0, winx = 0;
    vector<vector<int>> intBoard;
    for (auto& def : board) {
        intBoard.push_back({});

        for (auto& def1 : def)
            if (def1 == 'O') intBoard.back().push_back(1);
            else if (def1 == 'X') intBoard.back().push_back(-1);
            else intBoard.back().push_back(0);
    }

    int chackLX = 0;
    int chackRX = 0;
    for (int i = 0; i < 3; i++)
    {
        int chackR = 0;
        int chackD = 0;
        for (int j = 0; j < 3; j++) {
            chackR += intBoard[i][j];
            chackD += intBoard[j][i];
            count += intBoard[i][j];
        }
        ChackToBingo(chackR, wino, winx);
        ChackToBingo(chackD, wino, winx);
        chackLX += intBoard[i][i];
        chackRX += intBoard[2 - i][2 - i];
    }
    ChackToBingo(chackLX, wino, winx);
    ChackToBingo(chackRX, wino, winx);
    
    if ((wino >= 1 && count <= 0) ||
        (winx >= 1 && count != 0) ||
        (count < 0 || count > 2) ||
        (wino >= 1 && winx >= 1)) return 0;
    return 1;
}

실패

 

내부의 오류는 어느정도 해결하였으나, 아직 남아있었고, 조건항을 정상적으로 기입하지 못했다.


세 번째 시도

#include <string>
#include <vector>

using namespace std;

void ChackToBingo(const int& input, int& X, int& O)
{
    if (input == 3) X++;
    else if (input == -3) O++;
}

int solution(vector<string> board) {

    int count = 0;
    int wino = 0, winx = 0;
    vector<vector<int>> intBoard;
    for (auto& def : board) {
        intBoard.push_back({});

        for (auto& def1 : def)
            if (def1 == 'O') intBoard.back().push_back(1);
            else if (def1 == 'X') intBoard.back().push_back(-1);
            else intBoard.back().push_back(0);
    }

    int chackLX = 0;
    int chackRX = 0;
    for (int i = 0; i < 3; i++)
    {
        int chackR = 0;
        int chackD = 0;
        for (int j = 0; j < 3; j++) {
            chackR += intBoard[i][j];
            chackD += intBoard[j][i];
            count += intBoard[i][j];
        }
        ChackToBingo(chackR, wino, winx);
        ChackToBingo(chackD, wino, winx);
        chackLX += intBoard[i][i];
        chackRX += intBoard[2 - i][i];
    }
    ChackToBingo(chackLX, wino, winx);
    ChackToBingo(chackRX, wino, winx);
    
    if ((wino >= 1 && count <= 0) ||
        (winx >= 1 && count != 0) ||
        (count < 0 || count > 1) ||
        (wino >= 1 && winx >= 1)) return 0;
    return 1;
}

성공

 

조건항에 대해 ChackRX의 오류가 있었다. 우측 상단부터 대각선으로 중간, 하단을 검사해야 하는데, 우측하단을 검사하고 있엇다.

 

그리고 조건항에 대해서 좀 더 확인하고 조건을 다시 넣으니 정상성공.

 

오류를 해결하기 위해 사실 더 많은 시도횟수가 있었다.

728x90

'코딩테스트 문제 풀이' 카테고리의 다른 글

유사 칸토어 비트열  (0) 2024.05.14
억억단을 외우자  (0) 2024.04.26
두 원 사이의 정수 쌍  (0) 2024.03.15
(2024 KAKAO WINTER INTERNSHIP) n + 1 카드게임  (0) 2024.03.11
바탕화면 정리  (0) 2024.03.04