[파이썬] 백준 19237번 어른 상어
작성:
백준 #19237 어른 상어
# 1 이상 M 이하의 자연수 상어
# 1이 가장 강력한 상어
# N x N 격자
# 상어에 따라, 바라보는 방향에 따라 이동 방향의 우선순위가 다르다
# 1. 아무 냄새가 없는 칸
# 2. 자신의 냄새가 있는 칸
# - 가능한 칸이 여러 개면 특정 우선순위를 따른다
# 출력: 1번 상어만 격자에 남게 되는 시간
# 1000초가 넘어도 다른 상어가 격자에 남아있다면 -1 출력
# 1. 상어의 위치 저장 2차원 배열 loc
# 2. 상어의 이동 우선순위 저장 배열 directions
# 3. 상어 번호 & 냄새 남아있는 배열 trace (빈칸: [0, 0])
# 냄새가 있는 좌표를 따로 set에 저장해두며 갱신 (trace_left)
# 4. 상어번호: 좌표, 방향 저장하는 딕셔너리 shark {1: (2, 0, 4)}
# 모든 상어를 한번씩 이동시키며 1, 3, 4를 갱신한다.
# 4에서 쫒겨난 상어는 없애버린다.
def move(num, ny, nx, y, x, d): # loc, trace, shark 갱신
global k
loc[ny][nx] = num
loc[y][x] = 0
trace[ny][nx][0], trace[ny][nx][1] = num, k
trace_left.add((ny, nx))
shark[num] = (ny, nx, d)
def add_temp(num, ny, nx, y, x, d):
if temp.get((ny, nx)):
temp.get((ny, nx)).append((num, ny, nx, y, x, d))
else:
temp[(ny, nx)] = [(num, ny, nx, y, x, d)]
N, M, k = map(int, input().split())
loc = [[0 for i in range(N)] for j in range(N)]
directions = [0] + [[0] + [[] for j in range(4)] for k in range(M)]
trace = [[[0, 0] for i in range(N)] for j in range(N)]
trace_left = set()
shark = dict()
dy = [0, -1, 1, 0, 0]
dx = [0, 0, 0, -1, 1]
for i in range(N):
line = list(map(int, input().split()))
for j in range(N):
if line[j]:
loc[i][j] = line[j]
shark[line[j]] = (i, j, 0)
trace[i][j][0], trace[i][j][1] = line[j], k
trace_left.add((i, j))
dir_init = list(map(int, input().split()))
for i in range(1, len(dir_init) + 1):
y, x, zero = shark.get(i)
shark[i] = (y, x, dir_init[i-1])
for i in range(1, M+1):
for j in range(1, 5):
directions[i][j] = list(map(int, input().split()))
temp = dict()
for t in range(1, 1001):
update = trace_left.copy()
for num in shark.keys():
y, x, d = shark.get(num)
direc = directions[num][d]
has_blank = False
for i in range(4):
ny = y + dy[direc[i]]
nx = x + dx[direc[i]]
if 0 <= ny < N and 0 <= nx < N and not trace[ny][nx][0]:
has_blank = True
add_temp(num, ny, nx, y, x, direc[i])
break
if not has_blank:
for i in range(4):
ny = y + dy[direc[i]]
nx = x + dx[direc[i]]
if 0 <= ny < N and 0 <= nx < N and trace[ny][nx][0] == num:
add_temp(num, ny, nx, y, x, direc[i])
break
# trace 시간 갱신
for y, x in update:
trace[y][x][1] -= 1
if not trace[y][x][1]:
trace[y][x][0] = 0
trace_left.remove((y, x))
for coor in temp.keys():
if len(temp.get(coor)) == 1: move(*temp.get(coor)[0])
else:
lst = sorted(temp.get(coor))
move(*lst[0])
for j in range(1, len(lst)):
shark.pop(lst[j][0])
if len(shark) == 1 and shark.get(1):
break
temp.clear()
else:
t = -1
print(t)
댓글남기기