카카오 - 프렌즈4블록

문제

블라인드 공채를 통과한 신입 사원 라이언은 신규 게임 개발 업무를 맡게 되었다. 이번에 출시할 게임 제목은 “프렌즈4블록”.
같은 모양의 카카오프렌즈 블록이 2×2 형태로 4개가 붙어있을 경우 사라지면서 점수를 얻는 게임이다.

만약 판이 위와 같이 주어질 경우, 라이언이 2×2로 배치된 7개 블록과 콘이 2×2로 배치된 4개 블록이 지워진다. 같은 블록은 여러 2×2에 포함될 수 있으며, 지워지는 조건에 만족하는 2×2 모양이 여러 개 있다면 한꺼번에 지워진다.

블록이 지워진 후에 위에 있는 블록이 아래로 떨어져 빈 공간을 채우게 된다.

만약 빈 공간을 채운 후에 다시 2×2 형태로 같은 모양의 블록이 모이면 다시 지워지고 떨어지고를 반복하게 된다.

위 초기 배치를 문자로 표시하면 아래와 같다.

TTTANT
RRFACC
RRRFCC
TRRRAA
TTMMMF
TMMTTJ

각 문자는 라이언(R), 무지(M), 어피치(A), 프로도(F), 네오(N), 튜브(T), 제이지(J), 콘(C)을 의미한다

입력으로 블록의 첫 배치가 주어졌을 때, 지워지는 블록은 모두 몇 개인지 판단하는 프로그램을 제작하라.

입력

  • 입력으로 판의 높이 m, 폭 n과 판의 배치 정보 board가 들어온다.
  • 2 ≦ n, m ≦ 30
  • board는 길이 n인 문자열 m개의 배열로 주어진다. 블록을 나타내는 문자는 대문자 A에서 Z가 사용된다.

출력

입력으로 주어진 판 정보를 가지고 몇 개의 블록이 지워질지 출력하라.

풀이

똑같은 블록을 지우고 위에 칸을 내리는 부분에서 애를 먹었다. 그 부분만 짜는데 40분 넘게 걸린듯 하다.
나머지 메커니즘은 다음과 같다.
1. string 벡터를 쭉 둘러보면서 4개의 똑같은 블록이 모여있는지 확인
2. 모여있으면 대문자 블록을 소문자로 변화
3. 한번 다 돌려봤으면 이제 소문자 부분 블록을 제거하며서 제거한 블록 위의 칸을 아래로 당기기

역시 코드를 짤 때는 설계도를 그리고 하는게 낫다... 얼른 아이패드 왔으면 ㅇㅅㅇ

코드

테스터는 https://jay-ji.tistory.com/13?category=732905 블로그에서 인용했다.

#include <string>
#include <vector>
#include <iostream>
using namespace std;

bool compBlock(vector <string> board, int i, int j) {
    if (toupper(board[i][j]) == toupper(board[i + 1][j]))
        if (toupper(board[i][j]) == toupper(board[i][j + 1]))
            if (toupper(board[i][j]) == toupper(board[i + 1][j + 1]))
                return true;
    return false;
}

int changeBlock(vector<string>* board, int i, int j, int answer)
{
    int n;
    if (isupper((*board)[i][j]))
    {
        (*board)[i][j] += 32;
        answer++;
    }
    if (isupper((*board)[i + 1][j])) {
        (*board)[i + 1][j] += 32;
        answer++;
    }
    if (isupper((*board)[i][j + 1]))
    {
        (*board)[i][j + 1] += 32;
        answer++;
    }
    if (isupper((*board)[i + 1][j + 1]))
    {
        (*board)[i + 1][j + 1] += 32;
        answer++;
    }

    return answer;
}

int solution(int m, int n, vector<string> board) {
    int answer = 0;
    bool finish = false;
    bool isChange = false;
    int l;

    while (!finish)
    {
        for (int i = 0; i < m - 1; i++)
        {
            for (int j = 0; j < n - 1; j++) {
                cout << i << ' ' << j << '\n';
                if (board[i][j] != ' ' && compBlock(board, i, j))
                {
                    answer = changeBlock(&board, i, j, answer);
                    isChange = true;
                }
            }
        }
        for (int i = 0; i < board.size(); i++) {
            cout << board[i] << endl;
            if (i == board.size() - 1) {
                for (int j = 0; j < n; j++) cout << '-';
                cout << '\n';
            }
        }
        if (!isChange)
            finish = true;
        if (isChange) {
            for (int i = 0; i < n; i++)
            {
                for (int j = m - 2; j >= 0; j--)
                {
                    for (int k = j; k < m - 1; k++)
                    {
                        if (board[k + 1][i] == ' ' || islower(board[k + 1][i]))
                        {
                            board[k + 1][i] = board[k][i];
                            board[k][i] = ' ';
                        }

                    }
                }
            }
        }
        for (int i = 0; i < board.size(); i++) {
            cout << board[i] << endl;
            if (i == board.size() - 1) {
                for (int j = 0; j < n; j++) cout << '-';
                cout << '\n';
            }
        }
        isChange = false;
    }

    return answer;
}

int main(void)
{
    string arr[] = { "CCBDE", "AAADE", "AAABF", "CCBBF" };
    //string arr2[] = { "TTTANT", "RRFACC", "RRRFCC", "TRRRAA", "TTMMMF", "TMMTTJ" };
    //string arr3[] = { "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA" };
    //string arr4[] = { "AAAAAA", "BBAATB", "BBAATB", "JJJTAA", "JJJTAA" };
    vector <string> testCase(arr, arr + (sizeof(arr) / sizeof(arr[0])));
    //vector <string> testCase2(arr2, arr2 + (sizeof(arr2) / sizeof(arr2[0])));
    //vector <string> testCase3(arr3, arr3 + (sizeof(arr3) / sizeof(arr3[0])));
    //vector <string> testCase4(arr4, arr4 + (sizeof(arr4) / sizeof(arr4[0])));

    cout << "사라지는 블럭 수 : " << solution(4, 5, testCase) << "\n" << endl;
    //cout << "사라지는 블럭 수 : " << solution(6, 6, testCase2) << "\n" << endl;
    //cout << "사라지는 블럭 수 : " << solution(5, 15, testCase3) << "\n" << endl;
    //cout << "사라지는 블럭 수 : " << solution(5, 6, testCase4) << "\n" << endl;

    return 0;
}

좋은 웹페이지 즐겨찾기