개발/algorithm

[백준 19237번] 어른 상어

zzi_on2 2022. 10. 4. 16:05

문제 링크

풀이

백준 상어 문제들은 다 복잡한 것 같다.. 

graph : 상어 번호와 남은 냄새 시간을 저장한다. 

shark : 상어의 번호가 key, 위치와 방향을 value로 저장한다. 

priorites : 상어의 방향 별 우선 순위를 저장한다. 

 

시간이 1000초 이하일 때까지 아래 과정을 반복한다. 

1. 낮은 번호부터, 상어 별 현재 위치에 냄새를 뿌릴 수 있는지 체크한다. 

- 빈 곳이거나, 같은 냄새가 있다면 뿌릴 수 있음 

- 둘 다 불가능하면 제거 

 

2. 낮은 번호부터, 상어 별 현재 방향 별, 우선 순위 방향에 따라 이동한다. 

- 빈 곳이면 냄새 뿌리기

- 빈 곳이 없다면, 자기 냄새와 같은 곳에 냄새 뿌리기 

- 둘 다 불가능하면 제거 

 

3. 냄새가 있는 곳 유지 시간 줄이기 

- graph에서 냄새가 있다면 유지 시간을 -1 한다. 

- 유지 시간이 0이 되었다면, 냄새 제거한다.

 

4. 시간 +1

 

# https://www.acmicpc.net/problem/19237

n, m, k = map(int,input().split())

graph = []

for _ in range(n):
    graph.append(list(map(int,input().split())))
    
# 상어의 위치와 초기방향을 딕셔너리로 저장 
shark = {}

# 위 아래 왼쪽 오른쪽 
dx =[-1,1,0,0]
dy = [0,0,-1,1]

# 상어의 초기 방향 
direct = list(map(int,input().split()))

for i in range(n):
    for j in range(n):
        if graph[i][j] != 0 :
            # 상어의 현재 위치, 초기 방향 저장 
            shark[graph[i][j]] = (i, j,  direct[graph[i][j]-1])
        graph[i][j] = None
        
# 상어의 방향 별 우선 순위 ( 위 아래 왼쪽 오른쪽 )
priorities = []

for _ in range(m*4):
    priorities.append(list(map(int,input().split())))
    
time = -1
while time <= 1000:
    
    # 1번 상어만 남았다면 중단 
    if len(shark) == 1 :
        print(time)
        exit(0)

    key = list(shark.keys())
    # 번호가 빠른 상어부터 이동 
    key.sort()
    
    # 자신의 위치에 냄새를 뿌림 
    for idx in key:
        # 비었으면 
        if graph[shark[idx][0]][shark[idx][1]] is None :
            # 상어 번호, 남은 냄새 시간 기록 
            graph[shark[idx][0]][shark[idx][1]] = [idx, k]
        # 자신의 냄새와 같다면, 
        elif graph[shark[idx][0]][shark[idx][1]][0] == idx:
            graph[shark[idx][0]][shark[idx][1]] = [idx,k]
        # 이미 상어가 있거나, 자신의 냄새와 달라서 이동할 수 없다면 
        else :
            del shark[idx]
        
    key  = list(shark.keys())
    key.sort()
    
    # 상어 이동 
    for idx in key:
        # 현재 위치와 방향 
        x, y, d = shark[idx]
        # 빈 곳으로 이동 가능한지 체크
        flag_blank = False
        
        for i in priorities[(idx-1) * 4 + (d-1)]:
            nx = x + dx[i-1]
            ny = y + dy[i-1]
            nd = i 
            
            if 0<=nx<n and 0<=ny<n:
                # 비어있으면 이동 가능 
                if graph[nx][ny] is None:
                    flag_blank = True 
                    # 상어 위치 갱신 
                    shark[idx] = [nx,ny,nd]
                    break 
        
        # 자신의 냄새와 같은 곳으로 이동 가능한지 체크         
        flag_same = False 
        
        if not flag_blank:
            for i in priorities[(idx-1) * 4 + (d-1)]:
                nx = x + dx[i-1]
                ny = y + dy[i-1]
                nd = i 
                
                if 0<= nx < n and 0<= ny < n:
                    if graph[nx][ny][0] == idx :
                        flag_same = True 
                        # 상어 위치 갱신 
                        shark[idx] = [nx,ny,nd]
                        break
        else :
            continue 
        # 빈 곳, 자신의 냄새와 같은 곳도 없다면 삭제 
        if not flag_same :
            del shark[idx]
            
    for i in range(n):
        for j in range(n):
            # 상어가 위치에 있다면 냄새 유지 횟수 줄이기 
            if graph[i][j] is not None:
                graph[i][j][1] -= 1 
                # 냄새 사라짐 
                if graph[i][j][1] == 0:
                    graph[i][j] = None 
    
    time +=1 
    
print(-1)