Skip to content

Commit f919e93

Browse files
committed
[level 2] Title: [PCCP 기출문제] 3번 / 충돌위험 찾기, Time: 972.68 ms, Memory: 89.1 MB -BaekjoonHub
1 parent 3edfcfe commit f919e93

File tree

2 files changed

+186
-0
lines changed

2 files changed

+186
-0
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# [level 2] [PCCP 기출문제] 3번 / 충돌위험 찾기 - 340211
2+
3+
[문제 링크](https://school.programmers.co.kr/learn/courses/30/lessons/340211?language=swift)
4+
5+
### 성능 요약
6+
7+
메모리: 89.1 MB, 시간: 972.68 ms
8+
9+
### 구분
10+
11+
코딩테스트 연습 > PCCP 기출문제
12+
13+
### 채점결과
14+
15+
정확성: 100.0<br/>합계: 100.0 / 100.0
16+
17+
### 제출 일자
18+
19+
2025년 09월 23일 18:49:33
20+
21+
### 문제 설명
22+
23+
<p>어떤 물류 센터는 로봇을 이용한 자동 운송 시스템을 운영합니다. 운송 시스템이 작동하는 규칙은 다음과 같습니다.</p>
24+
25+
<ol>
26+
<li>물류 센터에는 (r, c)와 같이 2차원 좌표로 나타낼 수 있는 <code>n</code>개의 포인트가 존재합니다. 각 포인트는 1~<code>n</code>까지의 서로 다른 번호를 가집니다.</li>
27+
<li>로봇마다 정해진 운송 경로가 존재합니다. 운송 경로는 <code>m</code>개의 포인트로 구성되고 로봇은 첫 포인트에서 시작해 할당된 포인트를 순서대로 방문합니다.</li>
28+
<li>운송 시스템에 사용되는 로봇은 <code>x</code>대이고, 모든 로봇은 0초에 동시에 출발합니다. 로봇은 1초마다 r 좌표와 c 좌표 중 하나가 1만큼 감소하거나 증가한 좌표로 이동할 수 있습니다.</li>
29+
<li>다음 포인트로 이동할 때는 항상 최단 경로로 이동하며 최단 경로가 여러 가지일 경우, r 좌표가 변하는 이동을 c 좌표가 변하는 이동보다 먼저 합니다.</li>
30+
<li>마지막 포인트에 도착한 로봇은 운송을 마치고 물류 센터를 벗어납니다. 로봇이 물류 센터를 벗어나는 경로는 고려하지 않습니다.</li>
31+
</ol>
32+
33+
<p><strong>이동 중 같은 좌표에 로봇이 2대 이상 모인다면 충돌할 가능성이 있는 위험 상황으로 판단합니다.</strong> 관리자인 당신은 현재 설정대로 로봇이 움직일 때 위험한 상황이 총 몇 번 일어나는지 알고 싶습니다. 만약 어떤 시간에 여러 좌표에서 위험 상황이 발생한다면 그 횟수를 모두 더합니다. </p>
34+
35+
<p>운송 포인트 <code>n</code>개의 좌표를 담은 2차원 정수 배열 <code>points</code>와 로봇 <code>x</code>대의 운송 경로를 담은 2차원 정수 배열 <code>routes</code>가 매개변수로 주어집니다. 이때 모든 로봇이 운송을 마칠 때까지 발생하는 위험한 상황의 횟수를 return 하도록 solution 함수를 완성해 주세요.</p>
36+
37+
<hr>
38+
39+
<h5>제한사항</h5>
40+
41+
<ul>
42+
<li>2 ≤ <code>points</code>의 길이 = <code>n</code> ≤ 100
43+
44+
<ul>
45+
<li><code>points[i]</code>는 <code>i + 1</code>번 포인트의 [<code>r 좌표</code>, <code>c 좌표</code>]를 나타내는 길이가 2인 정수 배열입니다.</li>
46+
<li>1 ≤ <code>r</code> ≤ 100</li>
47+
<li>1 ≤ <code>c</code> ≤ 100</li>
48+
<li>같은 좌표에 여러 포인트가 존재하는 입력은 주어지지 않습니다.</li>
49+
</ul></li>
50+
<li>2 ≤ <code>routes</code>의 길이 = 로봇의 수 = <code>x</code> ≤ 100
51+
52+
<ul>
53+
<li>2 ≤ <code>routes[i]</code>의 길이 = <code>m</code> ≤ 100</li>
54+
<li><code>routes[i]</code>는 <code>i + 1</code>번째 로봇의 운송경로를 나타냅니다. <code>routes[i]</code>의 길이는 모두 같습니다.</li>
55+
<li><code>routes[i][j]</code>는 <code>i + 1</code>번째 로봇이 <code>j + 1</code>번째로 방문하는 포인트 번호를 나타냅니다.</li>
56+
<li>같은 포인트를 연속으로 방문하는 입력은 주어지지 않습니다.</li>
57+
<li>1 ≤ <code>routes[i][j]</code> ≤ <code>n</code></li>
58+
</ul></li>
59+
</ul>
60+
61+
<hr>
62+
63+
<h5>입출력 예</h5>
64+
<table class="table">
65+
<thead><tr>
66+
<th>points</th>
67+
<th>routes</th>
68+
<th>result</th>
69+
</tr>
70+
</thead>
71+
<tbody><tr>
72+
<td>[[3, 2], [6, 4], [4, 7], [1, 4]]</td>
73+
<td>[[4, 2], [1, 3], [2, 4]]</td>
74+
<td>1</td>
75+
</tr>
76+
<tr>
77+
<td>[[3, 2], [6, 4], [4, 7], [1, 4]]</td>
78+
<td>[[4, 2], [1, 3], [4, 2], [4, 3]]</td>
79+
<td>9</td>
80+
</tr>
81+
<tr>
82+
<td>[[2, 2], [2, 3], [2, 7], [6, 6], [5, 2]]</td>
83+
<td>[[2, 3, 4, 5], [1, 3, 4, 5]]</td>
84+
<td>0</td>
85+
</tr>
86+
</tbody>
87+
</table>
88+
<hr>
89+
90+
<h5>입출력 예 설명</h5>
91+
92+
<p><strong>입출력 예 #1</strong></p>
93+
94+
<p><img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/production/43dea513-36b0-493b-bb52-ac5d9dc49bf4/%E1%84%8E%E1%85%AE%E1%86%BC%E1%84%83%E1%85%A9%E1%86%AF%E1%84%8B%E1%85%B1%E1%84%92%E1%85%A5%E1%86%B71.gif" title="" alt="충돌위험1.gif"></p>
95+
96+
<p>그림처럼 로봇들이 움직입니다. 3초가 지났을 때 1번 로봇과 2번 로봇이 (4, 4)에서 충돌할 위험이 있습니다. 따라서 1을 return 해야 합니다.</p>
97+
98+
<p><strong>입출력 예 #2</strong></p>
99+
100+
<p><img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/production/b1b127d3-679b-4d54-ac3f-1e3131e7a6fa/%E1%84%8E%E1%85%AE%E1%86%BC%E1%84%83%E1%85%A9%E1%86%AF%E1%84%8B%E1%85%B1%E1%84%92%E1%85%A5%E1%86%B72.gif" title="" alt="충돌위험2.gif"></p>
101+
102+
<p>그림처럼 로봇들이 움직입니다. 1, 3, 4번 로봇의 경로가 같아 이동하는 0 ~ 2초 내내 충돌 위험이 존재합니다. 3초에는 1, 2, 3, 4번 로봇이 모두 (4, 4)를 지나지만 위험 상황은 한 번만 발생합니다. </p>
103+
104+
<p>4 ~ 5초에는 1, 3번과 2, 4번 로봇의 경로가 각각 같아 위험 상황이 매 초 2번씩 발생합니다. 6초에 2, 4번 로봇의 충돌 위험이 발생합니다. 따라서 9를 return 해야 합니다.</p>
105+
106+
<p><strong>입출력 예 #3</strong></p>
107+
108+
<p><img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/production/eb0fe259-fe92-44fc-bddb-c55afac4e12f/%E1%84%8E%E1%85%AE%E1%86%BC%E1%84%83%E1%85%A9%E1%86%AF%E1%84%8B%E1%85%B1%E1%84%92%E1%85%A5%E1%86%B73.gif" title="" alt="충돌위험3.gif"></p>
109+
110+
<p>그림처럼 로봇들이 움직입니다. 두 로봇의 경로는 같지만 한 칸 간격으로 움직이고 2번 로봇이 5번 포인트에 도착할 때 1번 로봇은 운송을 완료하고 센터를 벗어나 충돌 위험이 없습니다. 따라서 0을 return 해야 합니다.</p>
111+
112+
113+
> 출처: 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import Foundation
2+
3+
func solution(_ points: [[Int]], _ routes: [[Int]]) -> Int {
4+
5+
// 포인트 번호를 인덱스로 사용하기 위한 맵
6+
let pointMap = Dictionary(uniqueKeysWithValues: (1...points.count).map { ($0, points[$0-1]) })
7+
8+
// 로봇들의 시간별 위치를 저장할 딕셔너리
9+
var robotPaths: [Int: [[Int]]] = [:]
10+
11+
// 각 로봇의 이동 경로를 시간 순서대로 계산하여 저장
12+
for (robotIndex, route) in routes.enumerated() {
13+
var currentPath: [[Int]] = []
14+
15+
var startPoint = pointMap[route[0]]!
16+
currentPath.append(startPoint) // 0초 위치 추가
17+
18+
for i in 0..<route.count - 1 {
19+
let start = pointMap[route[i]]!
20+
let end = pointMap[route[i+1]]!
21+
22+
// r 좌표 먼저 이동
23+
var r = start[0]
24+
while r != end[0] {
25+
r += (end[0] > r) ? 1 : -1
26+
currentPath.append([r, start[1]])
27+
}
28+
29+
// c 좌표 이동
30+
var c = start[1]
31+
while c != end[1] {
32+
c += (end[1] > c) ? 1 : -1
33+
currentPath.append([r, c])
34+
}
35+
}
36+
robotPaths[robotIndex] = currentPath
37+
}
38+
39+
// 모든 로봇이 운송을 마칠 때까지 필요한 최대 시간 계산
40+
var maxTime = 0
41+
for path in robotPaths.values {
42+
maxTime = max(maxTime, path.count)
43+
}
44+
45+
// 시간대별 충돌 횟수 계산
46+
var collisionCount = 0
47+
var checkedCollisions: Set<String> = [] // 중복 충돌 방지를 위한 Set
48+
49+
for time in 0..<maxTime {
50+
var timeCollisions: [String: Int] = [:] // 특정 시간대의 위치별 로봇 수
51+
52+
for robotIndex in 0..<routes.count {
53+
if let path = robotPaths[robotIndex], time < path.count {
54+
let location = path[time]
55+
let locationString = "\(location[0]),\(location[1])"
56+
timeCollisions[locationString, default: 0] += 1
57+
}
58+
}
59+
60+
// 충돌 위험이 있는 위치 확인
61+
for (location, count) in timeCollisions {
62+
if count >= 2 {
63+
// 이전에 확인하지 않은 충돌만 계산
64+
if !checkedCollisions.contains("\(time)-\(location)") {
65+
collisionCount += 1
66+
checkedCollisions.insert("\(time)-\(location)")
67+
}
68+
}
69+
}
70+
}
71+
72+
return collisionCount
73+
}

0 commit comments

Comments
 (0)