[BOJ-Code] 20061 - 모노미노도미노 2

Posted by DHniyeo Blog on April 4, 2024

문제 링크

💡 구현/시뮬레이션

Memory 2416KB Time 8ms Code Length 3313B

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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
// 얻은 점수와 초록색, 파란색 보드에 타일이 있는 칸의 개수를 구해라.
#include<iostream>
#include<vector>

using namespace std;

int N;
struct info {
	int t, y, x;
};
vector<info> vc;
int score = 0;

int tile[6][4][2];

void init() {
	cin >> N;
	for (int i = 0; i < N; i++) {
		int t, y, x;
		cin >> t >> y >> x;
		vc.push_back({ t,y,x });
	}
}
info swapinfo(info now) {
	info next;
	if (now.t == 1) next.t = 1;
	if (now.t == 2) next.t = 3;
	if (now.t == 3) next.t = 2;
	next.y = now.x;
	next.x = now.y;	
	return next;
}
void downtile(int tileidx, info now) {
	// t = 1 : (y, x)
	// t = 2 : (y, x) , (y, x + 1)
	// t = 3 : (y, x) , (y + 1, x)

	if (now.t == 1) {
		int y = 0;
		int x = now.x;
		while (true) {
			y++;
			if (y >= 6) break;
			if (tile[y][x][tileidx] == 1) break;
		}
		if (y > 0)y--;
		tile[y][x][tileidx] = 1;
	}
	if (now.t == 2) {
		int y1 = 0;
		int x1 = now.x;
		int y2 = 0;
		int x2 = now.x + 1;
		while (true) {
			y1++; y2++;
			if (y1 >= 6 || y2 >= 6) break;
			if (tile[y1][x1][tileidx] == 1 || tile[y2][x2][tileidx] == 1) break;
		}
		if (y1 > 0) y1--;
		if (y2 > 0) y2--;
		tile[y1][x1][tileidx] = 1;
		tile[y2][x2][tileidx] = 1;
	}
	if (now.t == 3) {
		int y1 = 0;
		int x1 = now.x;
		int y2 = 1;
		int x2 = now.x;
		while (true) {
			y1++; y2++;
			if (y1 >= 6 || y2 >= 6) break;
			if (tile[y1][x1][tileidx] == 1 || tile[y2][x2][tileidx] == 1) break;
		}
		if (y1 > 0)y1--; 
		if (y2 > 0)y2--;
		tile[y1][x1][tileidx] = 1;
		tile[y2][x2][tileidx] = 1;
	}
}
void deletehang(int index, int tileidx) {
	for (int i = index; i > 0; i--) {
		for (int j = 0; j < 4; j++) {
			tile[i][j][tileidx] = tile[i - 1][j][tileidx];
		}
	}
	for (int j = 0; j < 4; j++) { // 마지막 행 비우기
		tile[0][j][tileidx] = 0;
	}
}
void getscore(int tileidx) {
	vector<int> findidx; // 위에서 부터 당김
	for (int i = 0; i < 6; i++) {
		int cnt = 0;
		for (int j = 0; j < 4; j++) {
			if (tile[i][j][tileidx] == 1) {
				cnt++;
			}
		}
		if (cnt == 4) {
			score++;
			findidx.push_back(i);
		}
	}
	for (int i = 0; i < findidx.size(); i++) {
		deletehang(findidx[i], tileidx);
	}
}
void remainspecial(int tileidx) {
	int cnt = 0;
	for (int i = 0; i < 2; i++) {
		for (int j = 0; j < 4; j++) {
			if (tile[i][j][tileidx] == 1) {
				cnt++;
				break;
			}
		}
	}
	for (int i = 0; i < cnt; i++) {
		deletehang(5, tileidx); // 마지막행 내림.
	}
}

int getTileSum() {
	int cnt = 0;
	for (int i = 0; i < 6; i++) {
		for (int j = 0; j < 4; j++) {
			for (int k = 0; k < 2; k++) {
				if (tile[i][j][k] != 0) cnt++;
			}
		}
	}
	return cnt;
}
void printtile(int tileidx) { // debug 용
	cout << endl;
	if (tileidx == 0) cout << "초록 타일 : " << endl;
	else cout << "파란 타일 : " << endl;
	for (int i = 0; i < 6; i++) {
		for (int j = 0; j < 4; j++) {
			cout << tile[i][j][tileidx];
		}
		cout << endl;
	}
}


int main() {
	init();
	for (int i = 0; i < N; i++) {
		info now = vc[i];
		// 타일 배치 후 내리기
		downtile(0, now);
		downtile(1, swapinfo(now));
		//// 확인후 타일 삭제후 점수 올리기
		getscore(0);
		getscore(1);
		//// 0 or 1 칸에 남아 있으면 해당 칸 만큼 아래로 내리기
		remainspecial(0);
		remainspecial(1);

		//printtile(0);
		//printtile(1);
	}
	cout << score << endl;
	cout << getTileSum() << endl;
}

이 코드는 주어진 보드에 타일을 배치하고, 특정 조건에 따라 타일을 내리고 삭제하여 점수를 계산하는 것을 목적으로 한다.

init 함수에서는 입력값을 받아 구조체에 저장한다.

swapinfo 함수는 현재 타일의 정보를 받아서 회전시킨 후의 정보를 반환한다.

downtile 함수는 타일을 아래로 내리는 과정을 처리한다.

deletehang 함수는 한 줄이 꽉 찼을 때 그 줄을 지우고 위의 줄들을 아래로 내린다.

getscore 함수는 꽉 찬 줄이 있는지 확인하고 점수를 계산한다.

remainspecial 함수는 맨 윗줄에 타일이 있는 경우 해당 줄을 삭제하고 나머지 줄을 아래로 내린다.

getTileSum 함수는 보드 전체의 타일 개수를 반환한다.

main 함수에서는 각 타일을 배치하고 내리는 과정을 거친 후 점수를 계산하고 출력한다.


이 문제에서 실수했던 점은 배열을 내릴 때, 맨 위에 배열을 0으로 비워줘야 한다는 것이다.