[백준] 모노미노도미노 2
문제 설명
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;
}