당신은 표 편집 프로그램을 작성하고 있습니다.
표의 크기는 50 × 50으로 고정되어있고 초기에 모든 셀은 비어 있습니다.
각 셀은 문자열 값을 가질 수 있고, 다른 셀과 병합될 수 있습니다.
위에서 r번째, 왼쪽에서 c번째 위치를 (r, c)라고 표현할 때, 당신은 다음 명령어들에 대한 기능을 구현하려고 합니다.
아래는 UPDATE 명령어를 실행하여 빈 셀에 값을 입력하는 예시입니다.
| commands | 효과 |
|---|---|
| UPDATE 1 1 menu | (1,1)에 "menu" 입력 |
| UPDATE 1 2 category | (1,2)에 "category" 입력 |
| UPDATE 2 1 bibimbap | (2,1)에 "bibimbap" 입력 |
| UPDATE 2 2 korean | (2,2)에 "korean" 입력 |
| UPDATE 2 3 rice | (2,3)에 "rice" 입력 |
| UPDATE 3 1 ramyeon | (3,1)에 "ramyeon" 입력 |
| UPDATE 3 2 korean | (3,2)에 "korean" 입력 |
| UPDATE 3 3 noodle | (3,3)에 "noodle" 입력 |
| UPDATE 3 4 instant | (3,4)에 "instant" 입력 |
| UPDATE 4 1 pasta | (4,1)에 "pasta" 입력 |
| UPDATE 4 2 italian | (4,2)에 "italian" 입력 |
| UPDATE 4 3 noodle | (4,3)에 "noodle" 입력 |
위 명령어를 실행하면 아래 그림과 같은 상태가 됩니다.

아래는 MERGE 명령어를 실행하여 셀을 병합하는 예시입니다.
| commands | 효과 |
|---|---|
| MERGE 1 2 1 3 | (1,2)와 (1,3) 병합 |
| MERGE 1 3 1 4 | (1,3)과 (1,4) 병합 |
위 명령어를 실행하면 아래와 같은 상태가 됩니다.

병합한 셀은 "category" 값을 가지게 되며 (1,2), (1,3), (1,4) 중 어느 위치를 선택하더라도 접근할 수 있습니다.
아래는 UPDATE 명령어를 실행하여 셀의 값을 변경하는 예시입니다.
| commands | 효과 |
|---|---|
| UPDATE korean hansik | "korean"을 "hansik"으로 변경 |
| UPDATE 1 3 group | (1,3) 위치의 셀 값을 "group"으로 변경 |
위 명령어를 실행하면 아래와 같은 상태가 됩니다.

아래는 UNMERGE 명령어를 실행하여 셀의 병합을 해제하는 예시입니다.
| commands | 효과 |
|---|---|
| UNMERGE 1 4 | 셀 병합 해제 후 원래 값은 (1,4)가 가짐 |
위 명령어를 실행하면 아래와 같은 상태가 됩니다.

실행할 명령어들이 담긴 1차원 문자열 배열 commands가 매개변수로 주어집니다. commands의 명령어들을 순서대로 실행하였을 때, "PRINT r c" 명령어에 대한 실행결과를 순서대로 1차원 문자열 배열에 담아 return 하도록 solution 함수를 완성해주세요.
| commands | result |
|---|---|
| ["UPDATE 1 1 menu", "UPDATE 1 2 category", "UPDATE 2 1 bibimbap", "UPDATE 2 2 korean", "UPDATE 2 3 rice", "UPDATE 3 1 ramyeon", "UPDATE 3 2 korean", "UPDATE 3 3 noodle", "UPDATE 3 4 instant", "UPDATE 4 1 pasta", "UPDATE 4 2 italian", "UPDATE 4 3 noodle", "MERGE 1 2 1 3", "MERGE 1 3 1 4", "UPDATE korean hansik", "UPDATE 1 3 group", "UNMERGE 1 4", "PRINT 1 3", "PRINT 1 4"] | ["EMPTY", "group"] |
| ["UPDATE 1 1 a", "UPDATE 1 2 b", "UPDATE 2 1 c", "UPDATE 2 2 d", "MERGE 1 1 1 2", "MERGE 2 2 2 1", "MERGE 2 1 1 1", "PRINT 1 1", "UNMERGE 2 2", "PRINT 1 1"] | ["d", "EMPTY"] |
sstream을 활용해서 공백을 구분자로 두고, 처음의 문자열을 검사해서 동작을 구분했다. UPDATE의 경우에는 1번의 명령어는 뒤에 3개의 값, 2번의 명령어는 뒤에 2개의 값이 들어오기 때문에 마지막 값이 공백인 경우에는 2번, 공백이 아닌 경우에는 1번으로 구분해서 구현했다.string table[2501];
int parent[2501];
int getID(int r, int c){
return (r - 1) * 50 + (c - 1);
}
int findParent(int x){
if (parent[x] == x) return x;
parent[x] = findParent(parent[x]);
return parent[x];
}
if(str == "UPDATE"){
string value1, value2, value;
ss >> value1 >> value2 >> value;
if (value != ""){
int r = stoi(value1), c = stoi(value2);
int id = getID(r, c);
int root = findParent(id);
table[root] = value;
}
...
if (str == "UPDATE"){
string value1, value2, value;
ss >> value1 >> value2 >> value;
if (value != ""){
...
}
else{
for(int i = 0; i <= 2500; i++){
int root = findParent(i);
if (parent[root] == root && table[root] == value1){
table[root] = value2;
}
}
}
}
else if(str == "MERGE"){
int r1, c1, r2, c2;
ss >> r1 >> c1 >> r2 >> c2;
int id1 = getID(r1, c1);
int id2 = getID(r2, c2);
id1 = findParent(id1);
id2 = findParent(id2);
if(id1 == id2) continue;
if (table[id1] == "" && table[id2] != ""){
parent[id1] = id2;
}else {
parent[id2] = id1;
}
}
else if(str == "UNMERGE"){
int r, c;
ss >> r >> c;
int id = getID(r, c);
int root = findParent(id);
string value = table[root];
vector<int> group;
for (int i = 0; i <= 2500; i++){
if (findParent(i) == root){
group.push_back(i);
}
}
for(int i : group){
parent[i] = i;
table[i] = "";
}
table[id] = value;
}
else if(str == "PRINT"){
int r, c;
ss >> r >> c;
int id = getID(r, c);
int root = findParent(id);
if(table[root] == ""){
answer.push_back("EMPTY");
}else{
answer.push_back(table[root]);
}
}
-> 모든 명령어에 대해 O(N)의 시간복잡도를 가지고 N은 2,500, 명령어는 최대 1,000개이기 때문에 알맞은 알고리즘으로 보인다.
#include <string>
#include <vector>
#include <sstream>
using namespace std;
string table[2501];
int parent[2501];
int getID(int r, int c){
return (r - 1) * 50 + (c - 1);
}
int findParent(int x){
if (parent[x] == x) return x;
parent[x] = findParent(parent[x]);
return parent[x];
}
vector<string> solution(vector<string> commands) {
vector<string> answer;
for(int i = 0; i <= 2500; i++){
table[i] = "";
parent[i] = i;
}
for(string command : commands){
stringstream ss;
string str;
ss.str(command);
ss >> str;
// 1. "UPDATE r c value" => (r, c) 값 : value
// 2. "UPDATE value1 value2" => value1 -> value2
// 3. "MERGE r1 c1 r2 c2" => (r1, c1) - (r2, c2)
// 4. "UNMERGE r c" => (r, c) 머지 해제 및 값 (r, c) 할당
// 5. "PRINT r c" => (r, c) 값 출력 (빈 경우 EMPTY)
if(str == "UPDATE"){
string value1, value2, value;
ss >> value1 >> value2 >> value;
if (value != ""){ // 1. "UPDATE r c value"
int r = stoi(value1), c = stoi(value2);
int id = getID(r, c);
int root = findParent(id);
table[root] = value;
}else{ // 2. "UPDATE value1 value2"
for(int i = 0; i <= 2500; i++){
int root = findParent(i);
if (parent[root] == root && table[root] == value1){
table[root] = value2;
}
}
}
}else if(str == "MERGE"){
int r1, c1, r2, c2;
ss >> r1 >> c1 >> r2 >> c2;
int id1 = getID(r1, c1);
int id2 = getID(r2, c2);
id1 = findParent(id1);
id2 = findParent(id2);
if(id1 == id2) continue;
if (table[id1] == "" && table[id2] != ""){
parent[id1] = id2;
}else {
parent[id2] = id1;
}
}else if(str == "UNMERGE"){
int r, c;
ss >> r >> c;
int id = getID(r, c);
int root = findParent(id);
string value = table[root];
vector<int> group;
for (int i = 0; i <= 2500; i++){
if (findParent(i) == root){
group.push_back(i);
}
}
for(int i : group){
parent[i] = i;
table[i] = "";
}
table[id] = value;
}else if(str == "PRINT"){
int r, c;
ss >> r >> c;
int id = getID(r, c);
int root = findParent(id);
if(table[root] == ""){
answer.push_back("EMPTY");
}else{
answer.push_back(table[root]);
}
}
}
return answer;
}