티스토리 뷰
https://school.programmers.co.kr/learn/courses/30/lessons/17679
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
1. 풀이
- 완전탐색이다
board 전체를 완전탐색해서 사라질 블록들을 찾아 제거하고, 다시 또 완전탐색해서 사라질 블록들을 찾아 제거하는 것을 반복한다. board는 한 번 탐색하고 블록을 제거하고나면 상태가 달라지기 때문에 다시 완전탐색을 해서 새로 사라질 블록을 찾아 제거해야 한다.
while True: # board 탐색을 반복할 while문
# board를 탐색하기 위한 이중 for문
for i in range(m - 1):
for j in range(n - 1):
board[i][j]
그러면 board를 탐색하기 위한 이중 for문과 해당 board 탐색을 반복할 while문이 해당 for을 감싼 형태로 코드가 구상된다.
- 삭제될 블록을 표시할 배열을 활용하자
블록이 삭제되는 조건은 board[i][j] == board[i][j + 1] == board[i + 1][j] == board[i + 1][j + 1]일 때이다. 즉, board를 완전탐색하면서 각 블록이 해당 조건을 만족한다면 (i, j), (i, j + 1), (i + 1, j), (i + 1, j + 1)이 삭제될 것이라고 표시해두어야 한다. 그 표시를 board와 동일한 크기의 2차원 배열 shell에다가 하자. 초기 값은 0이고, 삭제될 블록이라면 1로 초기화한다.
단, shell은 매번 초기화되어야 한다. 한 번 board를 탐색하고나서 블록이 삭제되면, 이제 새롭게 삭제될 블록을 찾아야 하기 때문이다.
- board의 열을 기준으로 쪼개서, 밑에서부터 블록을 삭제해 가자.
우선 블록은 좌우가 아닌, 아래로 이동하기 때문에 board를 열을 기준으로 쪼개서 생각하자. 보통 2차원 배열을 순회할 때 행(i)이 바깥 for문이고 열(j)이 안쪽 for문이지만, 이 경우엔 열(j)이 바깥 for문이고 행(i)이 안쪽 for문이다.
블록이 제거되면 그 위에 있는 블록들이 밀려 내려온다. 따라서 가장 마지막 행인 (m - 1)행부터 블록이 사라지는지 아닌지 확인해가며 0행으로 올라와야 한다. 만약 shell[i][j]가 1, 즉 삭제해야 하는 블록이라면 shell[x][j]가 0일 때까지 계속 i - 1, i - 2하면서 위의 행으로 올라가고, shell[x][j] == 0이면 board[i][j]에 board[x][j] 값을 넣어준다.
2. 정답 코드
def solution(m, n, board):
answer = 0
board = [list(b) for b in board]
while True:
shell = [[0] * n for _ in range(m)] # 1: 지워질 블록
popped = pop_blocks(m, n, board, shell)
if popped == 0:
break
answer += popped
for j in range(n):
for i in range(m - 1, 0, -1):
if shell[i][j] == 0:
continue
board[i][j] = "-"
for x in range(i - 1, -1, -1):
if shell[x][j] == 0:
board[i][j] = board[x][j]
board[x][j] = "-"
shell[i][j] = 0
shell[x][j] = 1
break
return answer
def pop_blocks(m, n, board, shell):
result = set()
for i in range(m - 1):
for j in range(n - 1):
if is_removable(board, i, j):
shell[i][j] = 1
shell[i][j + 1] = 1
shell[i + 1][j] = 1
shell[i + 1][j + 1] = 1
result.update({(i, j), (i, j + 1), (i + 1, j), (i + 1, j + 1)})
return len(result)
def is_removable(board, i, j):
return (
board[i][j] != "-"
and board[i][j] == board[i][j + 1] == board[i + 1][j] == board[i + 1][j + 1]
)
'코딩 테스트 > 프로그래머스' 카테고리의 다른 글
[프로그래머스] 리코쳇 로봇 파이썬 정답 풀이 (0) | 2025.04.18 |
---|---|
[프로그래머스] 유연근무제 파이썬 풀이 (0) | 2025.02.13 |
[프로그래머스] 택배상자 파이썬 풀이 (0) | 2024.06.03 |
[프로그래머스] 행렬의 곱셈 파이썬 풀이 (0) | 2024.05.14 |
[프로그래머스] 가장 먼 노드 파이썬 풀이 (0) | 2024.04.01 |