![[프로그래머스/JAVA] 340211번 충돌위험 찾기](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7U1fv%2FbtsKw7spPn5%2FZW13l8XbTDKs1qAzkMcKfk%2Fimg.png)

[프로그래머스/JAVA] 340211번 충돌위험 찾기Coding Test/Programmers2024. 11. 4. 17:21
문제
더보기
문제 링크
[PCCP 기출문제] 3번 / 충돌위험 찾기
https://school.programmers.co.kr/learn/courses/30/lessons/340211
문제 설명
어떤 물류 센터는 로봇을 이용한 자동 운송 시스템을 운영합니다. 운송 시스템이 작동하는 규칙은 다음과 같습니다.
- 물류 센터에는 (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 ≤ 100
-
- points[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
문제풀이
접근 방법
- 로봇의 이동 경로는 상하 이동 후 좌우 이동이다.
- 같은 시간에 로봇의 경로가 겹치면 충돌 위험상황이다.
- 시간별로 로봇의 이동 좌표를 저장해서 여러 로봇이 같이 지나가면 카운트를 센다.
- 좌표 계산하기 용이하게 Point 클래스를 정의한다.
- 특정 시간에 로봇들이 방문한 좌표들을 저장하고, 중복 방문된 좌표는 추가로 저장한다. -> visitedSet 과 crushedSet 을 저장하는 Log 클래스를 정의한다.
코드
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
public class P_340211 {
// 시간(초) 별 로봇들이 방문한 좌표 로그 맵
static final Map<Integer, Log> visitMap = new HashMap<>();
private static int solution(int[][] points, int[][] routes) {
// 솔루션마다 방문 맵을 초기화한다.
visitMap.clear();
int answer = 0;
// 로봇 별 루트를 돌면서 로그를 저장한다.
for (int[] route : routes) {
logRoute(points, route);
}
// 시간별로 저장된 방문 맵의 충돌 횟수를 더한다.
for (Log log : visitMap.values()) {
answer += log.getCrushedCount();
}
return answer;
}
// 특정 로봇의 이동 경로를 계산하고 방문한 좌표를 visitMap에 저장.
private static void logRoute(int[][] points, int[] route) {
// 현재 로봇 위치 좌표 (시작점)
Point cur = new Point(points[route[0]-1][0], points[route[0]-1][1]), target;
// 로봇이 좌표를 방문한 시간
int time = 0;
for (int i = 1; i < route.length; i++) {
// 이동 목표 좌표
target = new Point(points[route[i]-1][0], points[route[i]-1][1]);
// 현재 좌표와 목표 좌표가 같아질 때까지 반복
while (cur.x != target.x || cur.y != target.y) {
// 좌표 로깅
logPoint(cur.x, cur.y, time);
// x 좌표 먼저 이동 후 y 좌표 이동
if (cur.x != target.x) {
cur.x += (target.x > cur.x) ? 1 : -1;
} else if (cur.y != target.y) {
cur.y += (target.y > cur.y) ? 1 : -1;
}
// 이동 후 시간 증가
time++;
}
}
// 마지막 좌표 로깅
logPoint(cur.x, cur.y, time);
}
// 시간대 별 visitMap 좌표 로깅
private static void logPoint(int x, int y, int time) {
visitMap.putIfAbsent(time, new Log());
visitMap.get(time).visit(new Point(x,y));
}
// 로그 클래스
static class Log {
// 방문한 좌표 해시셋
HashSet<Point> visitedPoints = new HashSet<>();
// 충돌 위험 좌표 해시셋
HashSet<Point> crushedPoints = new HashSet<>();
private void visit(Point point) {
// 방문 해시셋에 추가가 안되면 (이미 다른 로봇이 방문해서) 충돌 위험 해시셋에 추가
if (!visitedPoints.add(point)) {
crushedPoints.add(point);
}
}
// 충돌 위험 해시셋 크기 반환
private int getCrushedCount() {
return crushedPoints.size();
}
}
// 좌표 저장 클래스
static class Point {
int x, y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
Point point = (Point) o;
return x == point.x && y == point.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
}
}
반응형
'Coding Test > Programmers' 카테고리의 다른 글
[프로그래머스/JAVA] 258712번 가장 많이 받은 선물 (0) | 2024.11.07 |
---|---|
[프로그래머스/JAVA] 258711번 도넛과 막대 그래프 (0) | 2024.11.06 |
[프로그래머스/JAVA] 250135번 아날로그 시계 (1) | 2024.11.02 |
[프로그래머스/JAVA] 340212번 퍼즐 게임 챌린지 (0) | 2024.10.31 |
[프로그래머스/JAVA] 250121번 데이터 분석 (1) | 2024.10.31 |

@dundun213 :: dundun213 님의 블로그
dundun213 님의 블로그 입니다.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!