[BOJ] Q11559 Puyo Puyo
[Programmers] Q11559 Puyo Puyo
Question
Language: Python
Difficulty: Gold 4
해당 문제는 시뮬레이션 유형의 문제로 아래 3가지 항목에 대한 구현만 수행하면 된다.
- 상하좌우로 연결되어 있는 블록 구하기
- 블록 제거
- 블록 아래로 이동
상세 구현은 아래와 같다.
- 상하좌우로 연결되어 있는 블록 구하기
#상하좌우로 연결되어 있는 부분 찾기
def find_component(visited,start_row,start_col):
component=[]
component_size=0
visited[start_row][start_col] = True
color=board[start_row][start_col]
queue=deque([(start_row,start_col)])
dy=[-1,0,1,0]
dx=[0,1,0,-1]
while queue:
row,col=queue.popleft()
component.append((row,col))
component_size+=1
for dir in range(4):
next_row=row+dy[dir]
next_col=col+dx[dir]
#격자 범위 조사
if next_row < 0 or next_row >= 12 or next_col < 0 or next_col>=6:
continue
#같은 색깔인지 조사
if board[next_row][next_col] != color:
continue
#방문 여부 조사
if visited[next_row][next_col]:
continue
visited[next_row][next_col]=True
queue.append((next_row,next_col))
return component_size,component
- 블록 제거
#연결되어 있는 블록 터뜨리기
def destroy_blocks(components):
global board
for component in components:
for row,col in component:
board[row][col]="."
- 블록 아래로 이동
#아래에 빈 공간이 있는 블록들 내리기
def drop_blocks():
global board
for start_col in range(6):
for start_row in range(10,-1,-1):
next_row=start_row
while (next_row+1) <= 11 and board[(next_row+1)][start_col] == ".":
next_row+=1
board[start_row][start_col],board[next_row][start_col]=board[next_row][start_col],board[start_row][start_col]
Solution
import sys
from collections import deque
#상하좌우로 연결되어 있는 부분 찾기
def find_component(visited,start_row,start_col):
component=[]
component_size=0
visited[start_row][start_col] = True
color=board[start_row][start_col]
queue=deque([(start_row,start_col)])
dy=[-1,0,1,0]
dx=[0,1,0,-1]
while queue:
row,col=queue.popleft()
component.append((row,col))
component_size+=1
for dir in range(4):
next_row=row+dy[dir]
next_col=col+dx[dir]
#격자 범위 조사
if next_row < 0 or next_row >= 12 or next_col < 0 or next_col>=6:
continue
#같은 색깔인지 조사
if board[next_row][next_col] != color:
continue
#방문 여부 조사
if visited[next_row][next_col]:
continue
visited[next_row][next_col]=True
queue.append((next_row,next_col))
return component_size,component
#연결되어 있는 블록 터뜨리기
def destroy_blocks(components):
global board
for component in components:
for row,col in component:
board[row][col]="."
#아래에 빈 공간이 있는 블록들 내리기
def drop_blocks():
global board
for start_col in range(6):
for start_row in range(10,-1,-1):
next_row=start_row
while (next_row+1) <= 11 and board[(next_row+1)][start_col] == ".":
next_row+=1
board[start_row][start_col],board[next_row][start_col]=board[next_row][start_col],board[start_row][start_col]
def print_board(title):
print(title)
for row in board:
print(*row)
def solution():
destroy_count=0
while True:
components=[]
components_size=0
visited=[[False] * 6 for _ in range(12)]
for row in range(12):
for col in range(6):
if not visited[row][col] and board[row][col] != ".":
component_size,component=find_component(visited,row,col)
#상하좌우로 4개이상 인접한 경우에만 해당 블록을 추가하도록 한다.
if component_size >=4 :
components.append(component)
components_size+=1
#더 이상 터뜨릴 블록이 없는 경우
if components_size ==0 :
break
#블록 제거하기
destroy_blocks(components)
destroy_count+=1
#빈공간 메꾸기
drop_blocks()
print(destroy_count)
if __name__ == "__main__":
board=[list(input()) for _ in range(12)]
solution()
댓글남기기