๋ณธ๋ฌธ์œผ๋กœ ๋ฐ”๋กœ๊ฐ€๊ธฐ
728x90
๐Ÿ”—๋ฌธ์ œ ๋ณด๋Ÿฌ๊ฐ€๊ธฐ
 

ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค

์ฝ”๋“œ ์ค‘์‹ฌ์˜ ๊ฐœ๋ฐœ์ž ์ฑ„์šฉ. ์Šคํƒ ๊ธฐ๋ฐ˜์˜ ํฌ์ง€์…˜ ๋งค์นญ. ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค์˜ ๊ฐœ๋ฐœ์ž ๋งž์ถคํ˜• ํ”„๋กœํ•„์„ ๋“ฑ๋กํ•˜๊ณ , ๋‚˜์™€ ๊ธฐ์ˆ  ๊ถํ•ฉ์ด ์ž˜ ๋งž๋Š” ๊ธฐ์—…๋“ค์„ ๋งค์นญ ๋ฐ›์œผ์„ธ์š”.

programmers.co.kr

 

๐Ÿ‘จ‍๐Ÿ’ปํ’€์ด ๊ณผ์ •

 

์ด ๋ฌธ์ œ๋ฅผ ํ’€๋ฉด์„œ ์ƒˆ๋กœ์šด ๊ตํ›ˆ์„ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค. ๋„ค....

"์‹ค๋ ฅ๋„ ์—†๋Š”๋ฐ, ๋˜์ง€๋„ ์•Š๋Š” ๋ฐฉ๋ฒ•์€ ์ ์šฉํ•˜์ง€ ๋ง์ž."

 

 

[์ฒซ ์‹œ๋„] ์‹คํŒจ

 

์ฒ˜์Œ ๊ตฌ์ƒํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ๊ฐ ์—ด์˜ ๋ฃจํŠธ(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;
}

 

 

 

728x90
๋ฐ˜์‘ํ˜•