충돌위험 찾기(L2)
문제 설명
어떤 물류 센터는 로봇을 이용한 자동 운송 시스템을 운영합니다. 운송 시스템이 작동하는 규칙은 다음과 같습니다.
- 물류 센터에는 (r, c)와 같이 2차원 좌표로 나타낼 수 있는
n
개의 포인트가 존재합니다. 각 포인트는 1~n
까지의 서로 다른 번호를 가집니다. - 로봇마다 정해진 운송 경로가 존재합니다. 운송 경로는
m
개의 포인트로 구성되고 로봇은 첫 포인트에서 시작해 할당된 포인트를 순서대로 방문합니다. - 운송 시스템에 사용되는 로봇은
x
대이고, 모든 로봇은 0초에 동시에 출발합니다. 로봇은 1초마다 r 좌표와 c 좌표 중 하나가 1만큼 감소하거나 증가한 좌표로 이동할 수 있습니다. - 다음 포인트로 이동할 때는 항상 최단 경로로 이동하며 최단 경로가 여러 가지일 경우, r 좌표가 변하는 이동을 c 좌표가 변하는 이동보다 먼저 합니다.
- 마지막 포인트에 도착한 로봇은 운송을 마치고 물류 센터를 벗어납니다. 로봇이 물류 센터를 벗어나는 경로는 고려하지 않습니다.
이동 중 같은 좌표에 로봇이 2대 이상 모인다면 충돌할 가능성이 있는 위험 상황으로 판단합니다. 관리자인 당신은 현재 설정대로 로봇이 움직일 때 위험한 상황이 총 몇 번 일어나는지 알고 싶습니다. 만약 어떤 시간에 여러 좌표에서 위험 상황이 발생한다면 그 횟수를 모두 더합니다.
운송 포인트 n
개의 좌표를 담은 2차원 정수 배열 points
와 로봇 x
대의 운송 경로를 담은 2차원 정수 배열 routes
가 매개변수로 주어집니다. 이때 모든 로봇이 운송을 마칠 때까지 발생하는 위험한 상황의 횟수를 return 하도록 solution 함수를 완성해 주세요.
제한사항
- 2 ≤
points
의 길이 =n
≤ 100points[i]
는i + 1
번 포인트의 [r 좌표
,c 좌표
]를 나타내는 길이가 2인 정수 배열입니다.- 1 ≤
r
≤ 100 - 1 ≤
c
≤ 100 - 같은 좌표에 여러 포인트가 존재하는 입력은 주어지지 않습니다.
- 2 ≤
routes
의 길이 = 로봇의 수 =x
≤ 100- 2 ≤
routes[i]
의 길이 =m
≤ 100 routes[i]
는i + 1
번째 로봇의 운송경로를 나타냅니다.routes[i]
의 길이는 모두 같습니다.routes[i][j]
는i + 1
번째 로봇이j + 1
번째로 방문하는 포인트 번호를 나타냅니다.- 같은 포인트를 연속으로 방문하는 입력은 주어지지 않습니다.
- 1 ≤
routes[i][j]
≤n
- 2 ≤
입출력 예
points | routes | result |
---|---|---|
[[3, 2], [6, 4], [4, 7], [1, 4]] | [[4, 2], [1, 3], [2, 4]] | 1 |
[[3, 2], [6, 4], [4, 7], [1, 4]] | [[4, 2], [1, 3], [4, 2], [4, 3]] | 9 |
[[2, 2], [2, 3], [2, 7], [6, 6], [5, 2]] | [[2, 3, 4, 5], [1, 3, 4, 5]] | 0 |
입출력 예 설명
입출력 예 #1
그림처럼 로봇들이 움직입니다. 3초가 지났을 때 1번 로봇과 2번 로봇이 (4, 4)에서 충돌할 위험이 있습니다. 따라서 1을 return 해야 합니다.
입출력 예 #2
그림처럼 로봇들이 움직입니다. 1, 3, 4번 로봇의 경로가 같아 이동하는 0 ~ 2초 내내 충돌 위험이 존재합니다. 3초에는 1, 2, 3, 4번 로봇이 모두 (4, 4)를 지나지만 위험 상황은 한 번만 발생합니다.
4 ~ 5초에는 1, 3번과 2, 4번 로봇의 경로가 각각 같아 위험 상황이 매 초 2번씩 발생합니다. 6초에 2, 4번 로봇의 충돌 위험이 발생합니다. 따라서 9를 return 해야 합니다.
입출력 예 #3
그림처럼 로봇들이 움직입니다. 두 로봇의 경로는 같지만 한 칸 간격으로 움직이고 2번 로봇이 5번 포인트에 도착할 때 1번 로봇은 운송을 완료하고 센터를 벗어나 충돌 위험이 없습니다. 따라서 0을 return 해야 합니다.
나의 풀이
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
from collections import defaultdict,Counter
def solution(points, routes):
answer = 0
robot_num=len(routes)
robots_routes=defaultdict(list)
max_r=0
for i in range(robot_num):
for j in range(1,len(routes[i])):
end_r,end_c=points[routes[i][j]-1]
start_r,start_c=points[routes[i][j-1]-1]
move_to=[end_r-start_r,end_c-start_c]
if j==1:
robots_routes[i].append([start_r,start_c])
if move_to[0]<0:
while move_to[0]:
start_r-=1
move_to[0]+=1
robots_routes[i].append([start_r,start_c])
elif move_to[0]>0:
while move_to[0]:
start_r+=1
move_to[0]-=1
robots_routes[i].append([start_r,start_c])
if move_to[1]<0:
while move_to[1]:
start_c-=1
move_to[1]+=1
robots_routes[i].append([start_r,start_c])
elif move_to[1]>0:
while move_to[1]:
start_c+=1
move_to[1]-=1
robots_routes[i].append([start_r,start_c])
max_r=max(max_r,len(robots_routes[i]))
for i in range(max_r):
tmp_r=[]
for rr in range(len(routes)):
if len(robots_routes[rr])>i:
tmp_r.append(tuple(robots_routes[rr][i]))
tmp_r=Counter(tmp_r)
for t in tmp_r:
if tmp_r[t]>1:
answer+=1
return answer
- robot들의 모든 route값을 저장한다.
- 그 후 route안에서 겹치는 값들이 있으면 충돌한 것이므로, Counter()를 이용하여 충돌 횟수를 구해준다.
- 구현이 너무 힘들었다.. 그래서 비효율적인 코드가 만들어졌다.