๐๋ฌธ์ ๋ณด๋ฌ๊ฐ๊ธฐ
๐จ๐ปํ์ด ๊ณผ์
์ด ๋ฌธ์ ๋ฅผ ํ๋ฉด์ ์๋ก์ด ๊ตํ์ ์ป์์ต๋๋ค. ๋ค....
"์ค๋ ฅ๋ ์๋๋ฐ, ๋์ง๋ ์๋ ๋ฐฉ๋ฒ์ ์ ์ฉํ์ง ๋ง์."
[์ฒซ ์๋] ์คํจ
์ฒ์ ๊ตฌ์ํ ๋ฐฉ๋ฒ์ผ๋ก๋ ๊ฐ ์ด์ ๋ฃจํธ(Root) ๋ธ๋ก ๋ฐฐ์ด์ ํตํด ์ํ์ข์ฐ ์ฐ๊ฒฐ๋ฆฌ์คํธ๋ก ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ์ด์์ต๋๋ค. ์๊ฐ์ ์ผ๋ก ํํํ์๋ฉด, ๋๊ฐ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
/*
- ๋ธ๋ก์ 'O'๋ก ํ๊ธฐ
- '-'๊ณผ '|'์ ์ฐ๊ฒฐ ๋งํฌ๋ฅผ ๋ปํจ
- []์ ๋ฐฐ์ด์ ๋ปํจ
*/
[O] [O] [O] [O] [O]
| | | | |
O - O - O - O - O
| | | | |
O - O - O - O - O
. . . . .
. . . . .
. . . . .
์ฒ์์๋ ๋ธ๋ก ์ญ์ ์ ์ ๋ธ๋ก ์ฌ๋ผ์ด๋ฉ์์ ์ค๋ฒํค๋๊ฐ ์๊ฒ ๋ค ํ๋ฉฐ ์ข์ ๋ณด์์ต๋๋ค. ๋ฐฐ์ด์์ ์ญ์ ํ๋ฉด ๊ฐ ์์๋ค๋งํผ ์์ง์ฌ์ผ ํ๋๊น์. ๊ทธ๋์ ํด๋น ๋ฐฉ๋ฒ์ ์ฝ๋๋ก ์์ฑํด ๋๊ฐ์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ํ๋ค๋ณด๋, ์๊ฐ์ด ๋๋ฌด๋ ์ค๋ ๊ฑธ๋ ธ๊ณ ๋ณด์์ด ๋ง์ด ํ์ํ๋ค๋ ๊ฑธ ๋๊ผ์ต๋๋ค. ๊ทธ๋์ ๋ฐ๋ก ๋์ ธ๋ฒ๋ ธ์ฃ ...ใ ใ
[๋ ๋ฒ์งธ ์๋] ์ฑ๊ณต
๊ทธ๋์ ๊ทธ๋ฅ ๋ฐฐ์ด ์์ฒด์์ ๊ตฌํํ๊ธฐ๋ก ํ์ต๋๋ค. ์ผ์ชฝ ๋งจ ์์์ ์ด ๋ฐฉํฅ์ผ๋ก ํ์์ ์์ํ ๊ฒ์ด๋ฏ๋ก, 2 X 2 ๊ตฌ๊ฐ์ ํ์ฌ ์์น์์ ์ค๋ฅธ์ชฝ, ์๋, ์ค๋ฅธ์ชฝ ์๋ ๋๊ฐ์ ๋ง ํ์ธํด์ฃผ๋ฉด ๋์์ต๋๋ค.
1. 2 X 2 ๋ธ๋ก ์ฒดํฌ
using Position = pair<int, int>;
vector<Position> directions { {0, 1}, {1, 0}, {1, 1} };
const char EMPTY = '#';
bool IsCanRemove(const vector<string>& board, int row, int col, int m, int n, char myCharacter) {
if (board[row][col] == EMPTY)
return false;
for (int i = 0; i < directions.size(); i++) {
int nextRow = row + directions[i].first;
int nextCol = col + directions[i].second;
if (nextRow < 0 or nextRow >= m or nextCol < 0 or nextCol >= n)
return false;
char symbol = board[nextRow][nextCol];
if (symbol == EMPTY)
return false;
if (board[nextRow][nextCol] != myCharacter)
return false;
}
return true;
}
์ ๊ฑฐ ๊ฐ๋ฅํ ๋ธ๋ก์ ์ฐพ์๋ค๋ฉด, ํด๋น ๋ธ๋ก ์ขํ๋ฅผ ๋ณ๋์ ๋ฐฐ์ด์ ์ ์ฅํด๋๋ฉด ๋ฉ๋๋ค.
vector<Position> removeTargets;
for (int row = 0; row < m; row++) {
for (int col = 0; col < n; col++) {
if (IsCanRemove(board, row, col, m, n, board[row][col])) {
removeTargets.emplace_back(row, col);
}
}
}
์ด ๊ณผ์ ์ ์ ๊ฑฐ ๊ฐ๋ฅํ ๋ธ๋ก์ด ์์ ๋๊น์ง ๋ฐ๋ณตํด์ผ ํ๋ฏ๋ก, do ~ while()๋ฌธ์ ์ฌ์ฉํด ์ฃผ์์ต๋๋ค.
bool isCanRemove = false;
do {
isCanRemove = false;
vector<Position> removeTargets;
for (int row = 0; row < m; row++) {
for (int col = 0; col < n; col++) {
if (IsCanRemove(board, row, col, m, n, board[row][col])) {
removeTargets.emplace_back(row, col);
isCanRemove = true;
}
}
}
// ์ ๊ฑฐ ๊ธฐ๋ฅ
// ์ฌ๋ผ์ด๋ฉ ๊ธฐ๋ฅ
} while (isCanRemove);
2. ๋ธ๋ก ์ ๊ฑฐํ๊ธฐ
์ด์ ์ ๋ณ๋๋ก ์ ์ฅํด ๋์ ์ ๊ฑฐ ๊ฐ๋ฅํ ๋ธ๋ก ์ขํ๋ ์ฌ๊ฐํ 4์นธ ์ค (0, 0)์ ์์น์ด๋ฏ๋ก, ์ค๋ฅธ์ชฝ, ์๋, ์ค๋ฅธ์ชฝ ์๋ ๋๊ฐ์ ์ ์ฐจ๋ก๋๋ก ์ ๊ฑฐํด์ฃผ๋ฉด ๋ฉ๋๋ค. ์ ๊ฑฐ ํ์๋ '#'์ผ๋ก ํ์์ต๋๋ค. ์ ๊ฑฐ๋์ง ์์ ๋ธ๋ก์ ์ ๊ฑฐํ ๋์๋ง ์นด์ดํธ๋ฅผ ํฉ๋๋ค.
void Remove(vector<string>& board, vector<Position> targets, int& removeCount) {
for (const auto position : targets) {
int row = position.first;
int col = position.second;
if (board[row][col] != EMPTY) {
board[row][col] = EMPTY;
removeCount++;
}
for (int i = 0; i < directions.size(); i++) {
int nextRow = row + directions[i].first;
int nextCol = col + directions[i].second;
if (board[nextRow][nextCol] != EMPTY) {
board[nextRow][nextCol] = EMPTY;
removeCount++;
}
}
}
}
3. ์ฑ์ธ ๋ธ๋ก ์์น์ ๋จ์ด๋จ๋ฆด ๋ธ๋ก ์์น ์ฐพ๊ธฐ
์ ์ผ ์๋ ํ(m - 1)๋ถํฐ ์ฌ๋ผ๊ฐ๋ฉด์ ๋น ๊ณต๊ฐ('#') ์ขํ๋ฅผ ์ฐพ์์ ์ ์ฅํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ ์ ํ๋ถํฐ ๋ค์ ์ฌ๋ผ๊ฐ๋ฉด์, ์๋๋ก ๋ด๋ ค์ฌ ์ฒซ ๋ฒ์งธ ๋ธ๋ก ์ขํ๋ฅผ ์ ์ฅํฉ๋๋ค.
void SlideToDown(vector<string>& board, int m, int n) {
for (int col = 0; col < n; col++) {
Position refillPos(-1, -1);
Position target(-1, -1);
int row = m - 1;
// ์ฑ์ธ ๊ณต๊ฐ ์ฐพ๊ธฐ
for (; row >= 0; row--) {
if (board[row][col] == EMPTY) {
refillPos = Position(row, col);
row--;
break;
}
}
// ์ ์ผ ๋จผ์ ๋ด๋ ค์ฌ ์ ์ฐพ๊ธฐ
for (; row >= 0; row--) {
if (board[row][col] != EMPTY) {
target = Position(row, col);
break;
}
}
bool isExistTarget = (target.first != -1) and (target.second != -1);
bool isExistRefillPlace = (refillPos.first != -1) and (refillPos.second != -1);
if (isExistTarget and isExistRefillPlace)
Replace(board, target, refillPos);
}
}
๋ ์ขํ๋ฅผ ์ฐพ์๋ค๋ฉด, ์๊น ์ฐพ์ ์๋๋ก ๋ด๋ ค์ฌ ์ฒซ ๋ฒ์งธ ๋ธ๋ก(target) ์์น๋ถํฐ 0๋ฒ ํ๊น์ง ์ญ ์ฌ๋ผ๊ฐ๋ฉด์ ์ฑ์ธ ๊ณต๊ฐ ์์น(refillPos)๋ก ๋ด๋ ค์ค๋๋ค. ๋ด๋ฆฐ ํ, target ๋ธ๋ก์ ๋น ๊ณต๊ฐ('#')์ผ๋ก ํ์ํ๊ณ , target๊ณผ refillPos์ ํ์ -1์ฉ ํด์ค๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ ํ์ผ๋ก ์ฌ๋ผ๊ฐ์ ๋ค์ ๋ฐ๋ณตํด์ค๋๋ค. ๋ง์ฝ, target์ด ๋น ๊ณต๊ฐ์ด๋ผ๋ฉด ๊ทธ ์ ํ์ผ๋ก ๊ทธ๋ฅ ๋์ด๊ฐ๋๋ค.
void Replace(vector<string>& board, Position target, Position refillPos) {
if (target.first < 0)
return;
int targetRow = target.first, targetCol = target.second;
int refillRow = refillPos.first, refillCol = refillPos.second;
Position newRefill = refillPos;
if (board[targetRow][targetCol] != EMPTY) {
board[refillRow][refillCol] = board[targetRow][targetCol];
board[targetRow][targetCol] = EMPTY;
newRefill = Position(refillRow - 1, refillCol);
}
Replace(board, Position(targetRow - 1, targetCol), newRefill);
}
์ด๋ ๊ฒ ๋ฐ๋ณตํด์ฃผ๋ฉด ๋ฉ๋๋ค.
โ๏ธ์์ค ์ฝ๋ ๋ฐ ๊ฒฐ๊ณผ
#include <string>
#include <vector>
using namespace std;
using Position = pair<int, int>;
vector<Position> directions { {0, 1}, {1, 0}, {1, 1} };
const char EMPTY = '#';
bool IsCanRemove(const vector<string>& board, int row, int col, int m, int n, char myCharacter) {
if (board[row][col] == EMPTY)
return false;
for (int i = 0; i < directions.size(); i++) {
int nextRow = row + directions[i].first;
int nextCol = col + directions[i].second;
if (nextRow < 0 or nextRow >= m or nextCol < 0 or nextCol >= n)
return false;
char symbol = board[nextRow][nextCol];
if (symbol == EMPTY)
return false;
if (board[nextRow][nextCol] != myCharacter)
return false;
}
return true;
}
void Remove(vector<string>& board, vector<Position> targets, int& removeCount) {
for (const auto position : targets) {
int row = position.first;
int col = position.second;
if (board[row][col] != EMPTY) {
board[row][col] = EMPTY;
removeCount++;
}
for (int i = 0; i < directions.size(); i++) {
int nextRow = row + directions[i].first;
int nextCol = col + directions[i].second;
if (board[nextRow][nextCol] != EMPTY) {
board[nextRow][nextCol] = EMPTY;
removeCount++;
}
}
}
}
void Replace(vector<string>& board, Position target, Position refillPos) {
if (target.first < 0)
return;
int targetRow = target.first, targetCol = target.second;
int refillRow = refillPos.first, refillCol = refillPos.second;
Position newRefill = refillPos;
if (board[targetRow][targetCol] != EMPTY) {
board[refillRow][refillCol] = board[targetRow][targetCol];
board[targetRow][targetCol] = EMPTY;
newRefill = Position(refillRow - 1, refillCol);
}
Replace(board, Position(targetRow - 1, targetCol), newRefill);
}
void SlideToDown(vector<string>& board, int m, int n) {
for (int col = 0; col < n; col++) {
Position refillPos(-1, -1);
Position target(-1, -1);
int row = m - 1;
// ์ฑ์ธ ๊ณต๊ฐ ์ฐพ๊ธฐ
for (; row >= 0; row--) {
if (board[row][col] == EMPTY) {
refillPos = Position(row, col);
row--;
break;
}
}
// ์ ์ผ ๋จผ์ ๋ด๋ ค์ฌ ์ ์ฐพ๊ธฐ
for (; row >= 0; row--) {
if (board[row][col] != EMPTY) {
target = Position(row, col);
break;
}
}
bool isExistTarget = (target.first != -1) and (target.second != -1);
bool isExistRefillPlace = (refillPos.first != -1) and (refillPos.second != -1);
if (isExistTarget and isExistRefillPlace)
Replace(board, target, refillPos);
}
}
int solution(int m, int n, vector<string> board) {
bool isCanRemove = false;
int answer = 0;
do {
isCanRemove = false;
vector<Position> removeTargets;
for (int row = 0; row < m; row++) {
for (int col = 0; col < n; col++) {
if (IsCanRemove(board, row, col, m, n, board[row][col])) {
removeTargets.emplace_back(row, col);
isCanRemove = true;
}
}
}
Remove(board, removeTargets, answer);
SlideToDown(board, m, n);
} while (isCanRemove);
return answer;
}
'๐คAlgorithm > Programmers' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Programmers] Lv2. ๊ฐ์ฅ ํฐ ์ | C++ (0) | 2023.06.26 |
---|---|
[Programmers] Lv2. ๋ค๋ฆฌ๋ฅผ ์ง๋๋ ํธ๋ญ | C++ (0) | 2023.06.25 |
[Programmers] Lv2. [3์ฐจ] ํ์ผ๋ช ์ ๋ ฌ | C++ (0) | 2023.06.24 |
[Programmers] Lv2. ๋ฐฉ๋ฌธ ๊ธธ์ด | C++ (0) | 2023.06.24 |
[Programmers] Lv2. ๊ฒ์ ๋งต ์ต๋จ๊ฑฐ๋ฆฌ | C++ (0) | 2023.06.22 |