BOJ/๐Ÿฅ‡

โ˜…Implementation&Simluation Upper-Advanced I - 1 Solvedโ˜…

metamong 2024. 3. 3.

โ˜… 19237 ์–ด๋ฅธ ์ƒ์–ด โ˜…

 

import sys
input=sys.stdin.readline
from collections import deque

N,M,k=map(int,input().split()) #NxNsize / M sharks / smell limit k
trace=[]
smell=[[0]*N for _ in range(N)]
sharks=deque()
shark_ds_priorities=[]
#shark_ds
dx,dy=['?',-1,1,0,0],['?',0,0,-1,1]
num_of_sharks=M

for i in range(N):
    l=list(map(int,input().split()))
    trace.append(l)
    for j in range(N):
        if l[j] != 0:
            sharks.append((i,j,l[j])) #x,y,shark_num
            smell[i][j] = k

shark_ds=list(map(int,input().split())) 

for _ in range(M):
    d=[]
    for _ in range(4):
        d.append(list(map(int,input().split())))
    shark_ds_priorities.append(d)

time=0
while 1:
    #spread smell
    for shark in sharks:
        smell[shark[0]][shark[1]] = k
    
    #move
    for _ in range(len(sharks)):
        x,y,num = sharks.popleft()

        #in shark-d priorities
        moved,my_trace=False,[]
        for next_d in shark_ds_priorities[num-1][shark_ds[num-1]-1]:
            nx,ny=x+dx[next_d],y+dy[next_d]
            if 0<=nx<N and 0<=ny<N:
                if smell[nx][ny] > 0: #if smell
                    if trace[nx][ny] == num: #if this is my trace
                        my_trace.append((nx,ny))
                    continue
                else: #if no smell -> move!
                    moved=True
                    sharks.append((nx,ny,num))
                    shark_ds[num-1]=next_d
                    break
        if not moved:
            nx,ny=my_trace[0][0],my_trace[0][1] #move to my trace(the 1st one in the list - based on priority)
            sharks.append((nx,ny,num))
            if nx==(x-1):
                shark_ds[num-1]=1
            elif nx==(x+1):
                shark_ds[num-1]=2
            elif ny==(y-1):
                shark_ds[num-1]=3
            else:
                shark_ds[num-1]=4
    
    #disappear smell
    for x in range(N):
        for y in range(N):
            if smell[x][y] > 0:
                smell[x][y] -=1
                if smell[x][y] == 0:
                    trace[x][y] = 0
    
    #after moving
    shark_list=[]
    while sharks:
        x,y,num = sharks.popleft()

        if trace[x][y] == 0: #no shark exists
            trace[x][y] = num
            shark_list.append((x,y,num))
        else: #if shark exists
            if num < trace[x][y]: #mine has more priority
                shark_list.remove((x,y,trace[x][y]))
                trace[x][y]=num
                num_of_sharks-=1
                shark_list.append((x,y,num))
            elif trace[x][y] < num:
                num_of_sharks-=1
            else: #trace[x][y] == num
                shark_list.append((x,y,num))
    for shark in shark_list:
        sharks.append(shark)
    time+=1
    if num_of_sharks == 1:
        print(time)
        break
    if time >= 1000:
        print(-1)
        break

 

โœˆ๏ธ 

โ‘  trace: ์ƒ์–ด๊ฐ€ ์œ„์น˜ํ•œ ์ƒํƒœ (2์ฐจ์› ๋ฐฐ์—ด)

โ‘ก smell: ๊ฐ ์ƒ์–ด์˜ smell ํ˜„ํ™ฉ (2์ฐจ์› ๋ฐฐ์—ด) 

โ‘ข sharks: deque() ์ค€๋น„: (x,y,shark_num) ํ˜•ํƒœ๋กœ ๊ฐ shark๋งˆ๋‹ค deque์— ๋„ฃ๊ธฐ (deque)

โ‘ฃ shark_ds: ๊ฐ ์ƒ์–ด์˜ ํ˜„ ๋ฐฉํ–ฅ ์ฃผ์–ด์ง (1์ฐจ์› list)

โ‘ค shark_ds_priorities: ๊ฐ ์ƒ์–ด์˜ ์ƒ/ํ•˜/์ขŒ/์šฐ์— ๋”ฐ๋ฅธ ๋ฐฉํ–ฅ ์šฐ์„ ์ˆœ์œ„ (2์ฐจ์› ๋ฐฐ์—ด)

 

โœˆ๏ธ ์ง„ํ–‰

" ๋งจ ์ฒ˜์Œ์—๋Š” ๋ชจ๋“  ์ƒ์–ด๊ฐ€ ์ž์‹ ์˜ ์œ„์น˜์— ์ž์‹ ์˜ ๋ƒ„์ƒˆ๋ฅผ ๋ฟŒ๋ฆฐ๋‹ค "

โ‘  sharks deque์— ์žˆ๋Š” ๊ฐ ๋ชจ๋“  ํ˜„์žฌ shark์˜ (x,y)์— smell k ๋ฟŒ๋ฆฌ๊ธฐ (smell[shark[0]][shark[1]] = k)

while 1:
    #spread smell
    for shark in sharks:
        smell[shark[0]][shark[1]] = k

" ๊ทธ ํ›„ 1์ดˆ๋งˆ๋‹ค ๋ชจ๋“  ์ƒ์–ด๊ฐ€ ๋™์‹œ์— ์ƒํ•˜์ขŒ์šฐ๋กœ ์ธ์ ‘ํ•œ ์นธ ์ค‘ ํ•˜๋‚˜๋กœ ์ด๋™ํ•˜๊ณ , "

โ‘ก len(sharks)๋งŒํผ sharks deque์—์„œ shark ๊บผ๋‚ด๋ฉด์„œ shark ์‹ค์ œ ์ด๋™

: shark_ds_priorities์— ๋”ฐ๋ผ nx,ny = x + dx[next_d], y + dy[next_d] update

#move
for _ in range(len(sharks)):
    x,y,num = sharks.popleft()

    #in shark-d priorities
    moved,my_trace=False,[]
    for next_d in shark_ds_priorities[num-1][shark_ds[num-1]-1]:
        nx,ny=x+dx[next_d],y+dy[next_d]

" ๊ฐ ์ƒ์–ด๊ฐ€ ์ด๋™ ๋ฐฉํ–ฅ์„ ๊ฒฐ์ •ํ•  ๋•Œ๋Š”, ๋จผ์ € ์ธ์ ‘ํ•œ ์นธ ์ค‘ ์•„๋ฌด ๋ƒ„์ƒˆ๊ฐ€ ์—†๋Š” ์นธ์˜ ๋ฐฉํ–ฅ์œผ๋กœ ์žก๋Š”๋‹ค "

โ‘ข ์ผ๋‹จ, nx์™€ ny๊ฐ€ 0์ด์ƒ N๋ฏธ๋งŒ์ธ ์ง€ (์ฆ‰ ๋ฒ”์œ„ ๋‚ด์— ์žˆ๋Š” ์ง€) ํ™•์ธ ํ›„, ์•„๋ฌด ๋ƒ„์ƒˆ๊ฐ€ ์—†๋‹ค๋ฉด ๋ฐ”๋กœ ์ด๋™! (์•„๋ž˜์˜ else๋ฌธ)

if 0<=nx<N and 0<=ny<N:
    if smell[nx][ny] > 0: #if smell
        if trace[nx][ny] == num: #if this is my trace
            my_trace.append((nx,ny))
        continue
    else: #if no smell -> move!
        moved=True
        sharks.append((nx,ny,num))
        shark_ds[num-1]=next_d
        break

→ ์ด๋™ํ–ˆ์œผ๋ฏ€๋กœ  moved = True / sharks deque์— updateํ•œ (nx,ny,num) append / shark_ds next_d ๋ฐฉํ–ฅ์œผ๋กœ update


" ์ธ์ ‘ํ•œ ์นธ ์ค‘ ์•„๋ฌด ๋ƒ„์ƒˆ๊ฐ€ ์—†๋Š” ์นธ์˜ ๋ฐฉํ–ฅ์ด ์—†๋‹ค๋ฉด ์ž์‹ ์˜ ๋ƒ„์ƒˆ๊ฐ€ ์žˆ๋Š” ์นธ์˜ ๋ฐฉํ–ฅ์œผ๋กœ ์žก๋Š”๋‹ค "

โ‘ฃ ๋ƒ„์ƒˆ๊ฐ€ ์žˆ๋‹ค๋ฉด(์•„๋ž˜ if smell[nx][ny]>0) trace list์— (nx,ny) append (์œ„ โ‘ข ์ฝ”๋“œ์™€ ์ค‘๋ณต)

if smell[nx][ny] > 0: #if smell
    if trace[nx][ny] == num: #if this is my trace
        my_trace.append((nx,ny))
    continue

โ‘ค ์•„๋ฌด ๋ƒ„์ƒˆ๊ฐ€ ์—†๋Š” ์นธ์ด ์—†๋‹ค๋ฉด(moved=False) my_trace []์˜ ์ฒซ๋ฒˆ์งธ ์›์†Œ์— ๋”ฐ๋ผ move / shark_ds update

if not moved:
    nx,ny=my_trace[0][0],my_trace[0][1] #move to my trace(the 1st one in the list - based on priority)
    sharks.append((nx,ny,num))
    if nx==(x-1):
        shark_ds[num-1]=1
    elif nx==(x+1):
        shark_ds[num-1]=2
    elif ny==(y-1):
        shark_ds[num-1]=3
    else:
        shark_ds[num-1]=4

โ‘ฅ ์ด๋™ ํ›„, ๊ฐ ๊ฒฉ์ž์˜ ๋ƒ„์ƒˆ๊ฐ€ 1์”ฉ ์‚ฌ๋ผ์ง„๋‹ค.

#disappear smell
for x in range(N):
    for y in range(N):
        if smell[x][y] > 0:
            smell[x][y] -=1
            if smell[x][y] == 0:
                trace[x][y] = 0

โ˜… ์ด ๋•Œ ์ฃผ์˜์ ! ๋ƒ„์ƒˆ๊ฐ€ 0์ด ๋œ๋‹ค๋Š” ๊ฑด ์ƒ์–ด๊ฐ€ ์‚ฌ๋ผ์ง„๋‹ค๋Š” ๋œป. ๊ทธ ๋•Œ๋Š” trace[x][y] = 0์œผ๋กœ ์„ค์ •ํ•ด ์ƒ์–ด๋ฅผ ์‚ฌ๋ผ์ง€๊ฒŒ ํ•ด์•ผ ํ•จ โ˜…


" ๋ชจ๋“  ์ƒ์–ด๊ฐ€ ์ด๋™ํ•œ ํ›„ ํ•œ ์นธ์— ์—ฌ๋Ÿฌ ๋งˆ๋ฆฌ์˜ ์ƒ์–ด๊ฐ€ ๋‚จ์•„ ์žˆ์œผ๋ฉด, ๊ฐ€์žฅ ์ž‘์€ ๋ฒˆํ˜ธ๋ฅผ ๊ฐ€์ง„ ์ƒ์–ด๋ฅผ ์ œ์™ธํ•˜๊ณ  ๋ชจ๋‘ ๊ฒฉ์ž ๋ฐ–์œผ๋กœ ์ซ“๊ฒจ๋‚œ๋‹ค. "

โ‘ฆ shark_list [] ๋งŒ๋“ค๊ณ  ๊ฐ shark ์šฐ์„ ์ˆœ์œ„์— ๋”ฐ๋ผ ์ œ๊ฑฐํ•˜๊ฑฐ๋‚˜ update / ๋งจ ๋งˆ์ง€๋ง‰์— shark_list๋ฅผ deque์— ๋„ฃ๊ธฐ

#after moving
shark_list=[]
while sharks:
    x,y,num = sharks.popleft()

    if trace[x][y] == 0: #no shark exists
        trace[x][y] = num
        shark_list.append((x,y,num))
    else: #if shark exists
        if num < trace[x][y]: #mine has more priority
            shark_list.remove((x,y,trace[x][y]))
            trace[x][y]=num
            num_of_sharks-=1
            shark_list.append((x,y,num))
        elif trace[x][y] < num:
            num_of_sharks-=1
        else: #trace[x][y] == num
            shark_list.append((x,y,num))
for shark in shark_list:
    sharks.append(shark)

โ‘ง ์ „ ๊ณผ์ •์ด ๋๋‚ฌ์œผ๋ฏ€๋กœ time +=1 / num_of_sharks == 1, ์ฆ‰ 1๋ฒˆ ์ƒ์–ด 1๋งˆ๋ฆฌ๋งŒ ๋‚จ๊ฑฐ๋‚˜ 1000์ดˆ ์ด์ƒ์ด๋ฉด print(time) ํ•˜๊ณ  ํ”„๋กœ๊ทธ๋žจ ์ข…๋ฃŒ.

time+=1
if num_of_sharks == 1:
    print(time)
    break
if time >= 1000:
    print(-1)
    break


 

 

 

 

 

 

๋Œ“๊ธ€