728x90
문제 보기
구현, 시뮬레이션 문제이다.
초록색 보드와 파란색 보드를 관리하는 두 배열(6x4, 4x6)을 선언하고 주어진 블록을 하나씩 처리하면 된다.
1 x 1 블록은 0, 1 x 2 블록은 1, -1, 2 x 1 블록은 2, -2 값으로 서로 연관이 있음을 표현하였다.
만약 연관 있는 블록에서 1칸이 사라지는 경우에는 남은 칸의 값을 0으로 업데이트하였다.
전체적인 알고리즘 수행 과정은 아래와 같다.
1. 블록 놓기
2. 꽉 찬 행, 열처리
3. 빈 공간 처리
4. 0 ~ 1 행 처리 순으로 진행된다.
하나의 블록에 대해서 2 ~ 4 과정을 한 번만 수행하는 것이 아니라 더 이상 바뀌는 부분이 없을 때까지 반복하였다.
코드
import sys
sys.setrecursionlimit(10 ** 9)
def find(array, flag): # 타일로 가득 찬 경우가 있는지 확인
global score
result = False
if flag == "G": # 초록색 타일
for i in range(6):
flag = True # 모두 꽉찬 상황이라고 가정
for j in range(4):
if array[i][j] is None:
flag = False
break
if flag: # 꽉찬 상황
result = True
score += 1
for k in range(4):
if array[i][k] in [None, 0, 1, -1]:
array[i][k] = None
elif array[i][k] == 2:
array[i][k] = None
array[i + 1][k] = 0
elif array[i][k] == -2:
array[i][k] = None
array[i - 1][k] = 0
else:
for j in range(6):
flag = True # 모두 꽉찬 상황이라고 가정
for i in range(4):
if array[i][j] is None:
flag = False
break
if flag: # 꽉찬 상황
result = True
score += 1
for k in range(4):
if array[k][j] in [None, 0, 2, -2]:
array[k][j] = None
elif array[k][j] == 1:
array[k][j] = None
array[k][j + 1] = 0
elif array[k][j] == -1:
array[k][j] = None
array[k][j - 1] = 0
return result
def delete(array, flag): # 마지막 행 or 열 삭제
if flag == "G": # 초록색 타일
for i in range(4):
if array[5][i] in [None, 0, 1, -1]:
array[5][i] = None
elif array[5][i] == -2: # 1개로 분해
array[5][i] = None
array[4][i] = 0
else:
for i in range(4):
if array[i][5] in [None, 0, 2, -2]:
array[i][5] = None
elif array[i][5] == -1: # 1개로 분해
array[i][5] = None
array[i][4] = 0
def sorting(array, flag): # 빈공간이 있는 경우 아래로 옮긴다.
result_flag = False
if flag == "G": # 초록색 타일
for i in range(4, -1, -1):
for j in range(4):
if array[i][j] is None:
continue
if array[i][j] == 0 and array[i + 1][j] is None:
result_flag = True
array[i][j] = None
array[i + 1][j] = 0
elif array[i][j] == 1 and array[i + 1][j] is None and array[i + 1][j + 1] is None:
result_flag = True
array[i][j] = None
array[i][j + 1] = None
array[i + 1][j] = 1
array[i + 1][j + 1] = -1
elif array[i][j] == -2 and array[i + 1][j] is None:
result_flag = True
array[i - 1][j] = None
array[i][j] = 2
array[i + 1][j] = -2
else:
for j in range(4, -1, -1):
for i in range(4):
if array[i][j] is None:
continue
if array[i][j] == 0 and array[i][j + 1] is None:
result_flag = True
array[i][j] = None
array[i][j + 1] = 0
elif array[i][j] == -1 and array[i][j + 1] is None:
result_flag = True
array[i][j - 1] = None
array[i][j] = 1
array[i][j + 1] = -1
elif array[i][j] == 2 and array[i][j + 1] is None and array[i + 1][j + 1] is None:
result_flag = True
array[i][j] = None
array[i + 1][j] = None
array[i][j + 1] = 2
array[i + 1][j + 1] = -2
return result_flag
def solve(green, blue, data):
x, y = data[1], data[2]
if data[0] == 1: # 1 x 1
# 초록색 타일에 놓기
pre = 0
for i in range(6):
if green[i][y] is None:
pre = i
else:
break
green[pre][y] = 0 # 1칸으로 구성
# 파란색 타일에 놓기
pre = 0
for i in range(6):
if blue[x][i] is None:
pre = i
else:
break
blue[x][pre] = 0 # 1칸으로 구성
elif data[0] == 2: # 1 x 2
# 초록색 타일에 놓기
pre = 0
for i in range(6):
if green[i][y] is None and green[i][y + 1] is None:
pre = i
else:
break
green[pre][y] = 1
green[pre][y + 1] = -1
# 파란색 타일에 놓기
pre = 0
for i in range(2, 6):
if blue[x][i] is None:
pre = i - 1
else:
break
blue[x][pre] = 1
blue[x][pre + 1] = -1
else: # 2 x 1
# 초록색 타일에 놓기
pre = 0
for i in range(2, 6):
if green[i][y] is None:
pre = i - 1
else:
break
green[pre][y] = 2
green[pre + 1][y] = -2
# 파란색 타일에 놓기
pre = 0
for i in range(6):
if blue[x][i] is None and blue[x + 1][i] is None:
pre = i
else:
break
blue[x][pre] = 2
blue[x + 1][pre] = -2
while True:
# 꽉 찬 행 열이 있는지 확인
a = find(green, "G")
b = find(blue, "B")
if not a and not b:
pass
else:
# 빈공간 관리
while True:
while True:
if not sorting(green, "G"):
break
while True:
if not sorting(blue, "B"):
break
# 꽉 찬 행 열이 있는지 확인
a = find(green, "G")
b = find(blue, "B")
if not a and not b:
break
# 초록색 0 ~ 1 행 확인
g_cnt = 0
for i in range(2):
for j in range(4):
if green[i][j] is not None:
g_cnt += 1
break
if g_cnt > 0:
for _ in range(g_cnt):
delete(green, "G")
while True:
if not sorting(green, "G"):
break
# 파란색 0 ~ 1 행 확인
b_cnt = 0
for j in range(2):
for i in range(4):
if blue[i][j] is not None:
b_cnt += 1
break
if b_cnt > 0:
for _ in range(b_cnt):
delete(blue, "B")
while True:
if not sorting(blue, "B"):
break
if g_cnt == 0 and b_cnt == 0:
break
def tile_count(array, flag): # 타일이 들어있는 칸의 개수 카운트
count = 0
if flag == "G":
for i in range(6):
for j in range(4):
if array[i][j] is not None:
count += 1
else:
for i in range(4):
for j in range(6):
if array[i][j] is not None:
count += 1
return count
if __name__ == "__main__":
n = int(input()) # 블록을 놓은 횟수
# 보드 초기화
green = [[None] * 4 for _ in range(6)]
blue = [[None] * 6 for _ in range(4)]
# 블록을 하나씩 놓는다.
score = 0
for i in range(n):
t, x, y = map(int, input().split())
solve(green, blue, (t, x, y))
# 출력
print(score)
print(tile_count(green, "G") + tile_count(blue, "B"))
728x90
'알고리즘 풀이 > 백준' 카테고리의 다른 글
[ 백준 17822 ] 원판 돌리기 - Python (0) | 2020.09.20 |
---|---|
[ 백준 17825 ] 주사위 윷놀이 - Python (0) | 2020.09.20 |
[ 백준 2206 ] 벽 부수고 이동하기 - Python (0) | 2020.09.03 |
[ 백준 1976 ] 여행 가자 - Python (0) | 2020.09.03 |
[ 백준 1826 ] 연료 채우기 - Python (0) | 2020.08.31 |