Skip to content

Commit 22efe7b

Browse files
committed
[level 3] Title: 퍼즐 조각 채우기, Time: 9.02 ms, Memory: 11.9 MB -BaekjoonHub
1 parent 85e32d5 commit 22efe7b

2 files changed

Lines changed: 209 additions & 0 deletions

File tree

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# [level 3] 퍼즐 조각 채우기 - 84021
2+
3+
[문제 링크](https://school.programmers.co.kr/learn/courses/30/lessons/84021)
4+
5+
### 성능 요약
6+
7+
메모리: 11.9 MB, 시간: 9.02 ms
8+
9+
### 구분
10+
11+
코딩테스트 연습 > 깊이/너비 우선 탐색(DFS/BFS)
12+
13+
### 채점결과
14+
15+
정확성: 100.0<br/>합계: 100.0 / 100.0
16+
17+
### 제출 일자
18+
19+
2026년 07월 29일 09:50:47
20+
21+
### 문제 설명
22+
23+
<p>테이블 위에 놓인 퍼즐 조각을 게임 보드의 빈 공간에 적절히 올려놓으려 합니다. 게임 보드와 테이블은 모두 각 칸이 1x1 크기인 정사각 격자 모양입니다. 이때, 다음 규칙에 따라 테이블 위에 놓인 퍼즐 조각을 게임 보드의 빈칸에 채우면 됩니다.</p>
24+
25+
<ul>
26+
<li>조각은 한 번에 하나씩 채워 넣습니다.</li>
27+
<li>조각을 회전시킬 수 있습니다.</li>
28+
<li>조각을 뒤집을 수는 없습니다.</li>
29+
<li>게임 보드에 새로 채워 넣은 퍼즐 조각과 인접한 칸이 비어있으면 안 됩니다.</li>
30+
</ul>
31+
32+
<p>다음은 퍼즐 조각을 채우는 예시입니다.</p>
33+
34+
<p><img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/production/ab4d8aa2-f282-4764-bb46-84d405464b90/puzzle_5.png" title="" alt="puzzle_5.png"></p>
35+
36+
<p>위 그림에서 왼쪽은 현재 게임 보드의 상태를, 오른쪽은 테이블 위에 놓인 퍼즐 조각들을 나타냅니다. 테이블 위에 놓인 퍼즐 조각들 또한 마찬가지로 [상,하,좌,우]로 인접해 붙어있는 경우는 없으며, 흰 칸은 퍼즐이 놓이지 않은 빈 공간을 나타냅니다. 모든 퍼즐 조각은 격자 칸에 딱 맞게 놓여있으며, 격자 칸을 벗어나거나, 걸쳐 있는 등 잘못 놓인 경우는 없습니다.</p>
37+
38+
<p>이때, 아래 그림과 같이 3,4,5번 조각을 격자 칸에 놓으면 규칙에 어긋나므로 불가능한 경우입니다.</p>
39+
40+
<p><img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/production/70e371ad-4306-412b-b53b-25208e52a513/puzzle_6.png" title="" alt="puzzle_6.png"></p>
41+
42+
<ul>
43+
<li>3번 조각을 놓고 4번 조각을 놓기 전에 위쪽으로 인접한 칸에 빈칸이 생깁니다.</li>
44+
<li>5번 조각의 양 옆으로 인접한 칸에 빈칸이 생깁니다.</li>
45+
</ul>
46+
47+
<p>다음은 규칙에 맞게 최대한 많은 조각을 게임 보드에 채워 넣은 모습입니다.</p>
48+
49+
<p><img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/production/dadd0bc1-8e38-4689-a480-26afa799a5a3/puzzle_7.png" title="" alt="puzzle_7.png"></p>
50+
51+
<p>최대한 많은 조각을 채워 넣으면 총 14칸을 채울 수 있습니다.</p>
52+
53+
<p>현재 게임 보드의 상태 <code>game_board</code>, 테이블 위에 놓인 퍼즐 조각의 상태 <code>table</code>이 매개변수로 주어집니다. 규칙에 맞게 최대한 많은 퍼즐 조각을 채워 넣을 경우, 총 몇 칸을 채울 수 있는지 return 하도록 solution 함수를 완성해주세요.</p>
54+
55+
<hr>
56+
57+
<h5>제한사항</h5>
58+
59+
<ul>
60+
<li>3 ≤ <code>game_board</code>의 행 길이 ≤ 50</li>
61+
<li><code>game_board</code>의 각 열 길이 = <code>game_board</code>의 행 길이
62+
63+
<ul>
64+
<li>즉, 게임 보드는 정사각 격자 모양입니다.</li>
65+
<li><code>game_board</code>의 모든 원소는 0 또는 1입니다.</li>
66+
<li>0은 빈칸, 1은 이미 채워진 칸을 나타냅니다.</li>
67+
<li>퍼즐 조각이 놓일 빈칸은 1 x 1 크기 정사각형이 최소 1개에서 최대 6개까지 연결된 형태로만 주어집니다.</li>
68+
</ul></li>
69+
<li><code>table</code>의 행 길이 = <code>game_board</code>의 행 길이</li>
70+
<li><code>table</code>의 각 열 길이 = <code>table</code>의 행 길이
71+
72+
<ul>
73+
<li>즉, 테이블은 <code>game_board</code>와 같은 크기의 정사각 격자 모양입니다.</li>
74+
<li><code>table</code>의 모든 원소는 0 또는 1입니다.</li>
75+
<li>0은 빈칸, 1은 조각이 놓인 칸을 나타냅니다.</li>
76+
<li>퍼즐 조각은 1 x 1 크기 정사각형이 최소 1개에서 최대 6개까지 연결된 형태로만 주어집니다.</li>
77+
</ul></li>
78+
<li><code>game_board</code>에는 반드시 하나 이상의 빈칸이 있습니다.</li>
79+
<li><code>table</code>에는 반드시 하나 이상의 블록이 놓여 있습니다.</li>
80+
</ul>
81+
82+
<hr>
83+
84+
<h5>입출력 예</h5>
85+
<table class="table">
86+
<thead><tr>
87+
<th>game_board</th>
88+
<th>table</th>
89+
<th>result</th>
90+
</tr>
91+
</thead>
92+
<tbody><tr>
93+
<td>[[1,1,0,0,1,0],[0,0,1,0,1,0],[0,1,1,0,0,1],[1,1,0,1,1,1],[1,0,0,0,1,0],[0,1,1,1,0,0]]</td>
94+
<td>[[1,0,0,1,1,0],[1,0,1,0,1,0],[0,1,1,0,1,1],[0,0,1,0,0,0],[1,1,0,1,1,0],[0,1,0,0,0,0]]</td>
95+
<td>14</td>
96+
</tr>
97+
<tr>
98+
<td>[[0,0,0],[1,1,0],[1,1,1]]</td>
99+
<td>[[1,1,1],[1,0,0],[0,0,0]]</td>
100+
<td>0</td>
101+
</tr>
102+
</tbody>
103+
</table>
104+
<hr>
105+
106+
<h5>입출력 예 설명</h5>
107+
108+
<p><strong>입출력 예 #1</strong></p>
109+
110+
<p>입력은 다음과 같은 형태이며, 문제의 예시와 같습니다.</p>
111+
112+
<p><img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/production/653b44d8-0fa6-42f8-aa9d-ceca639b0ad4/puzzle_9.png" title="" alt="puzzle_9.png"></p>
113+
114+
<p><strong>입출력 예 #2</strong></p>
115+
116+
<p>블록의 회전은 가능하지만, 뒤집을 수는 없습니다.</p>
117+
118+
119+
> 출처: 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
from collections import deque
2+
3+
dr = [-1,1,0,0]
4+
dc = [0,0,-1,1]
5+
6+
def block_sort(block):
7+
min_r = min(b[0] for b in block)
8+
min_c = min(b[1] for b in block)
9+
10+
sorted_block = [[r-min_r,c-min_c] for r,c in block]
11+
sorted_block.sort()
12+
13+
return sorted_block
14+
15+
def rotate(block):
16+
rotated = [[c,-r] for r,c in block]
17+
return block_sort(rotated)
18+
19+
def get_blocks(board,target_num):
20+
21+
row = len(board)
22+
23+
# 블럭 수집
24+
blocks = []
25+
visited = [[False] * row for _ in range(row)]
26+
27+
for i in range(row):
28+
for j in range(row):
29+
if board[i][j] == target_num and visited[i][j] == False:
30+
block = []
31+
q = deque()
32+
33+
q.append([i,j])
34+
visited[i][j] = True
35+
block.append([i,j])
36+
while(q):
37+
r,c = q.popleft()
38+
39+
for k in range(4):
40+
nr = r+dr[k]
41+
nc = c+dc[k]
42+
43+
# 유효 범위, 미방문, 블럭
44+
if 0 <= nr < row and 0 <= nc <row and visited[nr][nc] == False and board[nr][nc] == target_num:
45+
q.append([nr,nc])
46+
visited[nr][nc] = True
47+
block.append([nr,nc])
48+
49+
blocks.append(block_sort(block))
50+
return blocks
51+
52+
def solution(game_board, table):
53+
answer = 0
54+
55+
empty_spaces = get_blocks(game_board,0)
56+
57+
blocks = get_blocks(table,1)
58+
59+
used = [False] * len(blocks)
60+
61+
for empty in empty_spaces:
62+
for i, block in enumerate(blocks):
63+
if used[i]:
64+
continue
65+
if len(empty) != len(block):
66+
continue
67+
68+
is_matched = False
69+
current_block = block
70+
71+
for _ in range(4):
72+
if empty == current_block:
73+
is_matched = True
74+
break
75+
current_block = rotate(current_block)
76+
77+
if is_matched:
78+
used[i] = True
79+
answer += len(block)
80+
break
81+
82+
83+
return answer
84+
85+
# table에서 먼저 블럭에 대한 정보를 수집
86+
## 정보를 어떤 형태로 다루어야하지?
87+
### 일단 좌표 뽑아내고 각 좌표 더미에서 min 값으로 다 빼주면 좌표 정규화 가능
88+
# game_board 빈칸마다 넣어보는 것
89+
90+
# 1. 좌표 정규화 2. rotate zip 안됨. 좌표들 모음이라 3. 둘다 뽑아내서 모양 맞춘다고 생각하면 함수 분리

0 commit comments

Comments
 (0)