문제 링크
코드트리 | 코딩테스트 준비를 위한 알고리즘 정석
국가대표가 만든 코딩 공부의 가이드북 코딩 왕초보부터 꿈의 직장 코테 합격까지, 국가대표가 엄선한 커리큘럼으로 준비해보세요.
www.codetree.ai
풀이
계속 98%에서 틀렸습니다라고 떴는데, 그 이유는
격자 안 사람들 모두 편의점으로 한 칸 이동 -> 베이스 캠프로 이동 -> 도착한 베이스 캠프 & 편의점 지나갈 수 없음
해서 그런 것이었다.
문제의 조건을 만족 시키려면 아래와 같이 진행되어야 한다.
격자 안 사람들 모두 편의점으로 한 칸 이동 -> 도착한 편의점 지나갈 수 없음 -> 베이스 캠프로 이동 -> 도착한 베이스 캠프 지나갈 수 없음
1. 편의점으로 한 칸 이동 함수
우선 순위는 dx와 dy의 순서로 처리가 되므로 따로 체크해줄 필요가 없다.
현재 위치에서 가고싶은 편의점까지의 최단거리로 한칸 이동시켜준다.
def find_store(num):
now_x, now_y = people[num]
s_x, s_y = want[num]
q = deque()
# 현재 위치와 지나온 경로 저장
q.append((now_x,now_y,[]))
visited = [ [False] * n for _ in range(n)]
visited[now_x][now_y] = True
result = []
while q:
x, y, route = q.popleft()
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if nx < 0 or nx >= n or ny < 0 or ny >= n :
continue
# 도착한 베이스 캠프거나 편의점이면 지나갈 수 없음
if graph[nx][ny] == -1:
continue
if not visited[nx][ny] :
tmp = copy.deepcopy(route)
tmp.append(i)
visited[nx][ny] = True
q.append((nx,ny,tmp))
# 편의점에 도착했으면 지나온 경로 저장
if nx == s_x and ny == s_y:
result.append((len(tmp), tmp))
# 최단 거리, 우선 순위로 정렬
result.sort()
# 한 칸 이동
return now_x + dx[result[0][1][0]], now_y + dy[result[0][1][0]]
2. 베이스 캠프 이동 함수
가고싶은 편의점에서 가장 가까운 베이스 캠프로 이동시켜준다.
def find_base(x,y):
q = deque()
q.append((x,y,0))
base = []
visited = [ [False] * n for _ in range(n)]
visited[x][y] = True
while q :
x, y, cnt= q.popleft()
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if nx < 0 or nx >= n or ny < 0 or ny >= n :
continue
if graph[nx][ny] == -1:
continue
if not visited[nx][ny] :
# 베이스 캠프면, 걸리는 시간과 행,열 저장
if graph[nx][ny] == 1 :
base.append((cnt+1, nx, ny))
visited[nx][ny] = True
q.append((nx,ny,cnt+1))
# 시간, 행, 열 순으로 정렬
base.sort()
# 이동
return base[0][1], base[0][2]
3. 메인 루프
check 배열에 지나갈 수 없게 되는 편의점 위치를 저장해두었다가 격자 안의 사람들이 다 이동한 후에 지나갈 수 없게 표시해주었다.
while True :
# 이동할 수 없게 될 위치 저장
check = []
cnt = 0
for i in range(1,min(t,m+1)):
# 아직 편의점 도착하지 않은 사람들만 이동
if not done[i]:
# 편의점으로 한 칸 이동
x, y= find_store(i)
people[i] = [x,y]
# 편의점 도착했으면
if x == want[i][0] and y == want[i][1]:
# 지나갈 수 없음
check.append((x,y))
# 도착 완료 표시
done[i] = True
cnt += 1
else :
cnt += 1
# 모든 사람이 다 편의점 도착했으면 종료
if cnt == m :
break
# 격자 안의 사람들이 다 지나가고 난 후이므로, 지나갈 수 없게 표시
for a,b in check :
graph[a][b] = -1
check = []
# 베이스 캠프 이동
if t <= m :
x,y = find_base(want[t][0], want[t][1])
people[t] = [x,y]
# 지나갈 수 없음
graph[x][y] = -1
t += 1
전체 코드는 아래와 같다.
from collections import deque
import copy
dx = [-1,0,0,1]
dy = [0,-1,1,0]
n,m = map(int,input().split())
graph = []
for _ in range(n):
graph.append(list(map(int,input().split())))
def find_base(x,y):
q = deque()
q.append((x,y,0))
base = []
visited = [ [False] * n for _ in range(n)]
visited[x][y] = True
while q :
x, y, cnt= q.popleft()
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if nx < 0 or nx >= n or ny < 0 or ny >= n :
continue
if graph[nx][ny] == -1:
continue
if not visited[nx][ny] :
if graph[nx][ny] == 1 :
base.append((cnt+1, nx, ny))
visited[nx][ny] = True
q.append((nx,ny,cnt+1))
base.sort()
return base[0][1], base[0][2]
def find_store(num):
now_x, now_y = people[num]
s_x, s_y = want[num]
q = deque()
q.append((now_x,now_y,[]))
visited = [ [False] * n for _ in range(n)]
visited[now_x][now_y] = True
result = []
while q:
x, y, route = q.popleft()
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if nx < 0 or nx >= n or ny < 0 or ny >= n :
continue
if graph[nx][ny] == -1:
continue
if not visited[nx][ny] :
tmp = copy.deepcopy(route)
tmp.append(i)
visited[nx][ny] = True
q.append((nx,ny,tmp))
if nx == s_x and ny == s_y:
result.append((len(tmp), tmp))
result.sort()
return now_x + dx[result[0][1][0]], now_y + dy[result[0][1][0]]
people = [[] for _ in range(m+1)]
want = [[] for _ in range(m+1)]
for i in range(1,m+1):
a,b = map(int,input().split())
want[i] = [a-1,b-1]
t = 1
done= [False] * (m+1)
while True :
check = []
cnt = 0
for i in range(1,min(t,m+1)):
if not done[i]:
x, y= find_store(i)
people[i] = [x,y]
if x == want[i][0] and y == want[i][1]:
check.append((x,y))
done[i] = True
cnt += 1
else :
cnt += 1
if cnt == m :
break
for a,b in check :
graph[a][b] = -1
if t <= m :
x,y = find_base(want[t][0], want[t][1])
people[t] = [x,y]
graph[x][y] = -1
t += 1
print(t)
'개발 > algorithm' 카테고리의 다른 글
[코드트리] 포탑 부수기 - Python (2) | 2023.10.11 |
---|---|
[코드트리] 싸움땅 - Python (1) | 2023.10.11 |
[프로그래머스][level1] 달리기 경주 - python (0) | 2023.08.02 |
[Python] 반올림 처리하기 - 오사오입 (0) | 2023.03.05 |
[백준 12919번] A와 B 2 - python (0) | 2023.02.01 |