[백준] 모노미노도미노 2

2 minute read

문제 설명

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

제한사항

첫째 줄에 블록을 놓은 횟수 N(1 ≤ N ≤ 10,000)이 주어진다.
둘째 줄부터 N개의 줄에 블록을 놓은 정보가 한 줄에 하나씩 순서대로 주어지며, t x y와 같은 형태이다.

  • t = 1: 크기가 1×1인 블록을 (x, y)에 놓은 경우
  • t = 2: 크기가 1×2인 블록을 (x, y), (x, y+1)에 놓은 경우
  • t = 3: 크기가 2×1인 블록을 (x, y), (x+1, y)에 놓은 경우

블록이 차지하는 칸이 빨간색 칸의 경계를 넘어가는 경우는 입력으로 주어지지 않는다.


풀이

60분
오랜만에 삼성 스타일(?)의 문제를 풀었다. 이런 구현 문제의 핵심은 한 큐에 풀어내는 것이라고 생각하는데, 실수를 해버려서 시간이 오래걸렸다. 블록을 지운 뒤 위의 블록을 한칸씩 아래로 내려주는 과정에서 맨 위 블록에 0을 대입해주어야하는 것을 놓쳤었다. 구현 문제는 디버깅이 매우 귀찮고 오래걸리기 때문에 이런 사소한 실수를 찾아내기가 너무 오래걸리는 것 같다.

코드

// 05:01 ~ 06:02
// #pragma warning (disable:4996)
#include<iostream>
#include<vector>

using namespace std;

int boardR[4][4] = { 0, };
int score;

void erase(int board[][4], int x) {
	for (int j = 0; j < 4; ++j) {
		board[x][j] = 0;
		for (int i = x - 1; i >= 0; --i) {
			board[i + 1][j] = board[i][j];
		}
		board[0][j] = 0;
	}
}

void play(int board[][4], int y, int t) {
	int i = 0;
	for (i; i < 6; ++i) {
		if (board[i][y] == 1) break;
		if (t == 2 && board[i][y + 1] == 1) break;
		if ((t == 3 && i == 5) || (t == 3 && board[i + 1][y] == 1)) break;
	}
	--i;
	board[i][y] = 1;
	if(t == 2) board[i][y + 1] = 1;
	if(t == 3) board[i + 1][y] = 1;

	for (int i = 5; i >= 2; --i) {
		for (int j = 0; j < 4; ++j) {
			if (board[i][j] == 0) break;
			if (j == 3) {
				score += 1;
				erase(board, i);
				++i;
				break;
			}
		}
	}

	for (int i = 0; i < 2; ++i) {
		for (int j = 0; j < 4; ++j) {
			if (board[1][j] == 1) {
				erase(board, 5);
				break;
			}
		}
	}
}

int main()
{
	// freopen("input.txt", "r", stdin);

	int n, remained;
	int t, x, y;
	int boardG[6][4] = { 0, };
	int boardB[6][4] = { 0, };
	
	score = 0;
	remained = 0;
	cin >> n;


	while (n > 0) {
		cin >> t >> x >> y;

		play(boardG, y, t);

		if (t == 2) t = 3;
		else if (t == 3) t = 2;

		play(boardB, x, t);
		--n;
	}

	for (int i = 2; i < 6; ++i) {
		for (int j = 0; j < 4; ++j) {
			remained += boardG[i][j] + boardB[i][j];
		}
	}

	cout << score << endl << remained << endl;

	return 0;
}