알고리즘

프로그래머스 - 표 병합(150366)

SniKuz 2023. 8. 29. 14:31

링크 : https://school.programmers.co.kr/learn/courses/30/lessons/150366


문제 설명

당신은 표 편집 프로그램을 작성하고 있습니다.
표는 50*50 크기이며, 초기에 모든 셀은 비어 있습니다.
위에서 r번째, 왼쪽에서 c 번째 위치를 (r,c)라 표현할 때, 명령어들을 구현하려고 합니다.

명령어를 구현 한 후, 실행할 명령어들이 담긴 1차원 문자열 배열 commands가 주어질 때, commands 명령어를 순서대로 실행하고, PRINT 명령어에 대한 실행 결과를 순서대로 1차원 문자열 배열에 담아 return 하시오.

제한조건

1<=commands의 길이<=1000


아이디어

주어진 명령어 조건을 구현하는 문제.

MERGE, UNMERGE 문제에 경우 Union-Find 형태로 체크하면서 추가 작업.


코드

// https://school.programmers.co.kr/learn/courses/30/lessons/150366

#include <string>
#include <vector>
#include <iostream>

using namespace std;

vector<vector<string>> excel (51, vector<string>(51, ""));
vector<string> answer;
vector<vector<pair<int, int>>> merge(51, vector<pair<int, int>>(51));

void InitMerge()
{
    for(int i = 1; i < 51; i++)
    {
        for(int j = 1; j < 51; j++)
        {
            merge[i][j] = {i, j};
        }
    }
}

pair<int, int> Find(pair<int, int> path)
{
    pair<int, int> var = merge[path.first][path.second];
    if(var.first == path.first && var.second == path.second) return path;
    merge[path.first][path.second] = Find(merge[path.first][path.second]);
    return merge[path.first][path.second];
}

void Merge(pair<int, int> p1, pair<int, int> p2)
{
    pair<int, int> _p1 = Find(p1);
    pair<int, int> _p2 = Find(p2);
    if(_p1 == _p2) return;
    for(int i = 1; i < 51; i++)
        for(int j = 1; j < 51; j++)
        {
            if(merge[i][j] == _p2) merge[i][j] = _p1;
        }
    merge[_p2.first][_p2.second] = _p1;
}

void SplitString(string str, vector<string> &v)
{
    int prev = 0;
    int cur = str.find(" ");
    while(cur != string::npos)
    {
        v.push_back(str.substr(prev, cur - prev));
        prev = cur + 1;
        cur = str.find(" ", prev);
    }
    v.push_back(str.substr(prev, cur - prev));
}

void RunCmd(vector<string> cmd)
{
    if(cmd[0] == "UPDATE")
    {
        if(cmd.size() > 3)
        {
            int r = stoi(cmd[1]), c = stoi(cmd[2]);
            excel[r][c] = cmd[3];

            for(int i = 1; i < 51; i++)
            {
                for(int j = 1; j < 51; j++)
                {
                    if(merge[i][j] == merge[r][c])
                    {
                        excel[i][j] = cmd[3];
                    }
                }
            }
        }
        else
        {
            for(int i = 1; i < 51; i++)
                for(int j = 1; j < 51; j++)
                    if(excel[i][j] == cmd[1]) excel[i][j] = cmd[2];
        }
    }

    if(cmd[0] == "MERGE")
    {
        int r1 = stoi(cmd[1]), c1 = stoi(cmd[2]), r2= stoi(cmd[3]), c2 = stoi(cmd[4]);
        if(r1 == r2 && c1 == c2) return;
        Merge({r1, c1}, {r2, c2});
        string tempS = "UPDATE";
        vector<string> tempV;
        if(excel[r1][c1] == "")
        {
            tempS += " " + to_string(r1) + " " + to_string(c1) + " " + excel[r2][c2];
            SplitString(tempS, tempV);
            RunCmd(tempV);
        }
        else
        {
            tempS += " " + to_string(r2) + " " + to_string(c2) + " " + excel[r1][c1];
            SplitString(tempS, tempV);
            RunCmd(tempV);
        }
    }

    if(cmd[0] == "UNMERGE")
    {
        int r = stoi(cmd[1]), c = stoi(cmd[2]);
        for(int i = 1; i < 51; i++)
        {
            for(int j = 1; j < 51; j++)
            {
                if(i == r &&  j == c) continue;
                if(merge[i][j] == merge[r][c])
                {
                    excel[i][j] = "";
                    merge[i][j] = {i, j};
                }
            }
        }
        merge[r][c] = {r, c};
    }

    if(cmd[0] == "PRINT")
    {
        int r = stoi(cmd[1]), c = stoi(cmd[2]);
        auto temp = excel[r][c];
        if(temp == "") answer.push_back("EMPTY");
        else answer.push_back(temp);
    }
}

vector<string> solution(vector<string> commands) {
    InitMerge();
    for(auto cmdLine : commands)
    {
        vector<string> cmd;
        SplitString(cmdLine, cmd);
        RunCmd(cmd);
    }
    return answer;
}

피드백

1. 처음 작성했을 때 MERGE한 애들을 같이 처리안해주고 이상하게 푼 부분이 있어 다른 분이 올려두신 예외케이스를 보고 추가하여 확인...

2. 구현 문제가 작성하다 보면 어느 순간 이상하게 놓치고 있어서 계속 대략적인 전체 코드 짠 후 그걸 바탕으로 다시 짜는 경우가 많은 문제...