19237 - 어른 상어
info
- 문제 보기: 19237 - 어른 상어
- 소요 시간: 💥1시간 초과
- 풀이 언어:
python
- 체감 난이도: 4️⃣
- 리뷰 횟수: ✅
풀이 키워드
스포주의
구현
풀이 코드
info
- 메모리: 33752 KB
- 시간: 292 ms
import sys
from copy import deepcopy
input = sys.stdin.readline
n, m, k = 0, 0, 0
field = [] # 상어 맵
smell = [] # 냄새 맵
s_dir = [] # 상어 방향 정보
s_pri = [] # 상어 이동 우선순위 정보
out = 0 # 쫓겨난 상어 카운트
dy = [-1, 1, 0, 0]
dx = [0, 0, -1, 1] # T B L R
def update_smell():
global smell
for y in range(n):
for x in range(n):
# 냄새 있으면 -1
if smell[y][x][1] > 0:
smell[y][x][1] -= 1
# 상어의 위치면 [상어번호, k]로 갱신
if field[y][x] != 0:
smell[y][x] = [field[y][x], k]
def move():
nfield = deepcopy(field) # 이동 기록용. n제곱 스캔때문에 분리해야 함.
global s_dir, out
for y in range(n):
for x in range(n):
if field[y][x] == 0: # existence check
continue
# 상어 있으면
sdx = field[y][x] - 1 # shark index
d = s_dir[sdx] # 1 ~ 4
moved = False
#print('sdx:', sdx, '/ d:', d)
# 냄새 없는 곳 탐색
# 4방향을 s_pri 우선순위에 따라 처리
for nd in s_pri[sdx][d-1]: # 1 ~ 4
ny = y + dy[nd-1]
nx = x + dx[nd-1]
#print('nd:', nd, '/ ny:', ny, '/ nx:', nx)
if not (0 <= ny < n and 0 <= nx < n): # bound check
continue
# 냄새 없는 경우
if smell[ny][nx][1] == 0:
if nfield[ny][nx] == 0: # 상어도 없으면
nfield[ny][nx] = sdx + 1 # 바로 이동
else: # 상어 있으면
nfield[ny][nx] = min(nfield[ny][nx], sdx + 1) # 더 작은 상어 win
out += 1 # 상어 하나 out
#print('out')
nfield[y][x] = 0 # 이동 전 위치 처리
s_dir[sdx] = nd # 이동 후 방향 갱신
moved = True
break
if moved: # 다음 상어로 넘어가기
continue
# 아직 이동 못했으면 본인 냄새 탐색
# 4방향을 s_pri 우선순위에 따라 처리
for nd in s_pri[sdx][d-1]: # 1 ~ 4
ny = y + dy[nd-1]
nx = x + dx[nd-1]
if not (0 <= ny < n and 0 <= nx < n):
continue
if smell[ny][nx][0] == sdx + 1: # 자신의 냄새면
s_dir[sdx] = nd # 방향 업데이트
nfield[ny][nx] = field[y][x] # 이동
nfield[y][x] = 0 # 이동 전 위치 처리
break
return nfield
def solution():
global n, m, k, field, smell, s_dir, s_pri
n, m, k = map(int, input().split())
for _ in range(n):
field.append(list(map(int, input().split())))
smell.append([[0, 0] for _ in range(n)])
s_dir = list(map(int, input().split()))
for _ in range(m):
lst = []
for _ in range(4):
lst.append(list(map(int, input().split())))
s_pri.append(lst)
# simulate
for t in range(1, 1001):
update_smell()
# print(t)
# for line in smell:
# print(line)
field = move()
#print()
if out == m-1:
print(t)
return
print(-1)
if __name__ == '__main__':
solution()
풀이 해설
WIP
메모
- 삼성 문제 종특인데 이 문제처럼 for - if 구현 순서와 지문의 순서가 일치하지 않을 때가 있음.
- 문제 구조화 능지가 높아야 함.
- (x, y) -> (y, x) 로 앞뒤 바꾸어 구현해도 상관없는 문제임. 내 코드가 그렇게 풀었음.
- 처음 푸는데 2시간 반... 걸림 (디버깅 포함)