백준/구현

백엔드 20061 c++ "모노미노도미노 2" -PlusUltraCode-

PlusUltraCode 2025. 7. 21. 08:49

https://www.acmicpc.net/problem/20061

 

 

[필사 사고]

 단순 구현 문제라고 생각했지만 의외로 조건들이 많아서 힘들었다. 

블록들을 내리는 방식과

갱신되고

특정 조건에서 다시 update해주는게 처음 마주한 입장에서 다소 힘들었다.

[코드 해설]

1. dropGreen(int t, int x, int y)

초록색 보드에 블록을 떨어뜨리는 함수입니다.
블록의 종류(t)에 따라 다음과 같이 다르게 동작합니다:

  • t == 1: 1x1 크기의 블록입니다. 해당 열에서 가장 아래까지 빈 칸을 찾아 내려보내고, 해당 위치에 블록을 놓습니다.
  • t == 2: 1x2 가로 블록입니다. y열과 y+1열을 동시에 고려하면서 아래로 떨어뜨립니다. 두 칸 모두 비어있는 가장 아래 행을 찾아 그 행에 블록을 놓습니다.
  • t == 3: 2x1 세로 블록입니다. y열을 기준으로 두 행을 차지하므로, 아래로 두 칸을 차지할 수 있는 위치를 찾아 해당 두 칸에 블록을 놓습니다.

2. dropBlue(int t, int x, int y)

파란색 보드에 블록을 떨어뜨리는 함수입니다.
방향이 오른쪽이라는 점만 제외하면 dropGreen과 로직이 유사합니다.

  • t == 1: 1x1 블록입니다. x행의 가장 오른쪽까지 가면서 비어있는 위치를 찾고 해당 열에 놓습니다.
  • t == 2: 1x2 가로 블록입니다. 파란 보드에서는 같은 행의 연속된 두 칸이므로, 오른쪽으로 두 칸 모두 비어있는 곳을 찾아 블록을 놓습니다.
  • t == 3: 2x1 세로 블록입니다. 파란 보드에서는 x, x+1 두 행의 같은 열에 놓이므로, 오른쪽 열들 중 두 행이 모두 비어있는 열을 찾아 해당 열에 놓습니다.

3. cleanGreen()

초록 보드에서 점수를 얻는 처리 함수입니다.
가장 아래쪽 행부터 위로 2번 행까지 확인합니다.

  • 한 행이 모두 1로 가득 차 있다면 해당 행을 제거하고, 그 위의 모든 행을 한 칸씩 아래로 당깁니다.
  • 가장 위 행(0행)은 0으로 초기화합니다.
  • 한 줄이 지워지면 점수(score)를 1점 추가합니다.
  • 지운 이후에도 같은 행을 다시 확인해야 하므로, i++로 인덱스를 복원합니다.

4. cleanBlue()

파란 보드에서 점수를 얻는 처리 함수입니다.
방향이 오른쪽이라는 점만 다르고, cleanGreen과 거의 동일한 로직입니다.

  • 5번 열부터 2번 열까지 확인하며, 해당 열이 모두 1로 가득 차 있으면 지우고 점수를 1점 얻습니다.
  • 지운 열의 왼쪽 열들을 오른쪽으로 한 칸씩 밀고, 가장 왼쪽 열은 0으로 초기화합니다.
  • j++로 지운 열을 다시 검사합니다.

5. shiftGreen()

초록 보드의 연한 구역(0, 1행)에 블록이 존재하는 경우를 처리하는 함수입니다.

  • 0행 또는 1행에 블록이 존재하면, 존재하는 행의 수만큼 아래로 전체를 밀어야 합니다.
  • cnt는 연한 구역(0행, 1행)에 블록이 있는 행의 수입니다.
  • cnt만큼 전체를 아래로 한 칸씩 밀고, 가장 위 행(0행)은 0으로 초기화합니다.

이 로직은 **게임 규칙의 "연한 색 블록 처리"**를 구현한 것입니다.


6. shiftBlue()

파란 보드의 연한 구역(0, 1열)에 블록이 존재하는 경우를 처리하는 함수입니다.

  • 0열 또는 1열에 블록이 존재하면, 존재하는 열의 수만큼 전체를 오른쪽으로 밀어야 합니다.
  • cnt는 연한 구역(0열, 1열)에 블록이 있는 열의 수입니다.
  • cnt만큼 전체를 오른쪽으로 한 칸씩 밀고, 가장 왼쪽 열(0열)은 0으로 초기화합니다.

마찬가지로 **게임 규칙의 "연한 색 블록 처리"**를 구현한 것입니다.

[소스 코드]

#include <iostream>
#include <vector>

using namespace std;

int N, score = 0;
int green[6][4], blue[4][6];

void dropGreen(int t, int x, int y) {
	int r = 0;
	if (t == 1) {
		while (r + 1 < 6 && green[r + 1][y] == 0) r++;
		green[r][y] = 1;
	}
	else if (t == 2) {
		while (r + 1 < 6 && green[r + 1][y] == 0 && green[r + 1][y + 1] == 0)r++;
		green[r][y] = green[r][y + 1] = 1;
	}
	else {
		while (r + 2 < 6 && green[r + 2][y] == 0)r++;
		green[r][y] = green[r + 1][y] = 1;
	}
}

void dropBlue(int t, int x, int y) {
	int c = 0;
	if (t == 1) {
		while (c + 1 < 6 && blue[x][c + 1] == 0) c++;
		blue[x][c] = 1;
	}
	else if (t == 2) { // 가로 블록
		while (c + 2 < 6 && blue[x][c + 2] == 0) c++;
		blue[x][c] = blue[x][c + 1] = 1;
	}
	else { // 세로 블록
		while (c + 1 < 6 && blue[x][c + 1] == 0 && blue[x + 1][c + 1] == 0) c++;
		blue[x][c] = blue[x + 1][c] = 1;
	}
}

void cleanGreen() {
	for (int i = 5; i >= 2; i--) {
		bool full = true;
		for (int j = 0; j < 4; j++) {
			if (green[i][j] == 0)full = false;

		}
		if (full) {
			score++;
			for (int r = i; r >= 1; r--) {
				for (int c = 0; c < 4; c++) {
					green[r][c] = green[r - 1][c];
				}
			}
			for (int c = 0; c < 4; c++)green[0][c] = 0;
			i++;
		}
	}
}

void cleanBlue() {
	for (int j = 5; j >= 2; j--) {
		bool full = true;
		for (int i = 0; i < 4; i++)
			if (blue[i][j] == 0) full = false;
		if (full) {
			score++;
			for (int c = j; c >= 1; c--)
				for (int r = 0; r < 4; r++)
					blue[r][c] = blue[r][c - 1];
			for (int r = 0; r < 4; r++) blue[r][0] = 0;
			j++;
		}
	}
}

void shiftGreen() {
	int cnt = 0;
	for (int i = 0; i <= 1; i++) {
		for (int j = 0; j < 4; j++) {
			if (green[i][j]) {
				cnt++;
				break;
			}
		}

	}
	while (cnt--) {
		for (int i = 5; i >= 1; i--) {
			for (int j = 0; j < 4; j++) {
				green[i][j] = green[i - 1][j];
			}
		}
		for (int j = 0; j < 4; j++)green[0][j] = 0;
	}
}

void shiftBlue() {
	int cnt = 0;
	for (int j = 0; j <= 1; j++) {
		for (int i = 0; i < 4; i++) {
			if (blue[i][j]) {
				cnt++;
				break;
			}
		}
	}
	while (cnt--) {
		for (int j = 5; j >= 1; j--)
			for (int i = 0; i < 4; i++)
				blue[i][j] = blue[i][j - 1];
		for (int i = 0; i < 4; i++) blue[i][0] = 0;
	}
}