[BOJ] 19235 - 모노미노도미노
주어진 기능을 충실하게 구현하면 되는 문제다.
처음에는 어디서 많이 풀어봤던 그 문제를 푼 방법 그대로 접근했더니 TC가 나오지 않아서 굉장히.. 멘붕했었던 문제다.
다행히도 그 문제와 조건이 달라 한 줄이 삭제 될 경우 블록이 내려갈 수 있을 때 까지 바닥으로 내려가야 하는 조건이 새로 있었다.
처음에는 그냥 블록을 놓는 과정이 한 번만 필요했기 때문에 따로 함수를 정의하지 않고 내부에서 for문으로 처리해주었지만, 바뀐 조건으로 인해 블록을 떨어뜨리는 함수를 새로 정의하고 일일이 그 함수를 통해 처리하도록 해주었다.
최대한 내가 코딩하기 편한 방식을 사용했기 때문에 나에게 철저히 맞춰진 코드다.
가로필드와 세로 필드는 하나의 함수로 처리할 수 있도록 가로필드를 시계방향으로 90도 돌린 형태로 처리해주었다.
소스코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <iostream>
using namespace std;
int k, board[2][6][4];
bool is_in_range(int x, int y) {
return x >= 0 && x < 6 && y >= 0 && y < 4;
}
bool can_putit(int x, int y, int mode, int type) {
if (mode == 1) {
return is_in_range(x, y) && board[type][x][y] == 0;
}
else if (mode == 2) { // 가로 블럭
return is_in_range(x, y) && board[type][x][y] == 0 &&
is_in_range(x, y + 1) && board[type][x][y + 1] == 0;
}
else { // 세로 블럭
return is_in_range(x, y) && board[type][x][y] == 0 &&
is_in_range(x + 1, y) && board[type][x + 1][y] == 0;
}
}
void putit(int x, int y, int mode, int type, int val) {
if (mode == 2) { // 가로 블럭
board[type][x][y + 1] = val;
}
else if (mode == 3) { // 세로 블럭
board[type][x + 1][y] = val;
}
board[type][x][y] = val;
}
void dropit(int col, int mode, int type, int val, int start) {
int now = 5;
for (int j = start; j < 6; j++) {
if (!can_putit(j, col, mode, type)) {
now = j - 1;
break;
}
}
putit(now, col, mode, type, val);
}
int get_point() {
int rtn = 0;
for (int type = 0; type < 2; type++) {
while (true) {
int cnt = 0;
for (int i = 5; i > 0; i--) {
bool ck = false;
for (int j = 0; j < 4; j++) {
if (board[type][i][j] == 0) ck = true;
}
if (ck) continue;
// 열을 삭제한다
for (int j = 0; j < 4; j++) {
board[type][i][j] = 0;
}
cnt++;
}
if (cnt == 0) break;
rtn += cnt;
for (int i = 4; i >= 0; i--) {
for (int j = 0; j < 4; j++) {
if (board[type][i][j] != 0 && board[type][i + 1][j] == 0) {
int now = board[type][i][j];
if (j != 0 && now == board[type][i][j - 1])continue;
if (now == board[type][i - 1][j]) { // mode 3
putit(i - 1, j, 3, type, 0);
dropit(j, 3, type, now, i + 1);
}
else if (j != 3 && now == board[type][i][j + 1]) { // mode 2
putit(i, j, 2, type, 0);
dropit(j, 2, type, now, i + 1);
j++;
}
else { // mode 1
putit(i, j, 1, type, 0);
dropit(j, 1, type, now, i + 1);
}
}
}
}
}
}
return rtn;
}
void moveit() {
for (int type = 0; type < 2; type++) {
int cnt = 0;
for (int i = 0; i < 2; i++) {
bool ck = false;
for (int j = 0; j < 4; j++) {
if (board[type][i][j] != 0) ck = true;
}
if (ck) cnt++;
}
for (int i = 5; i >= 0; i--) {
for (int j = 0; j < 4; j++) {
if (i >= 2) board[type][i][j] = board[type][i - cnt][j];
else board[type][i][j] = 0;
}
}
}
}
int main(void) {
int n, a, b, c, ans = 0;
scanf("%d", &n);
for (k = 1; k <= n; k++) {
scanf("%d %d %d", &a, &b, &c);
dropit(c, a, 0, k, 0);
b = 3 - b;
if (a == 2) {
a = 3;
}
else if (a == 3) {
a = 2;
b -= 1;
}
dropit(b, a, 1, k, 0);
ans += get_point();
moveit();
}
int cnt = 0;
for (int type = 0; type < 2; type++) {
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 4; j++) {
if (board[type][i][j] != 0) cnt++;
}
}
}
printf("%d\n%d", ans, cnt);
return 0;
}
This post is licensed under CC BY 4.0 by the author.
Comments powered by Disqus.