diff --git "a/seahee/week5/\353\260\260\353\213\254.java" "b/seahee/week5/\353\260\260\353\213\254.java" new file mode 100644 index 0000000..c5081a3 --- /dev/null +++ "b/seahee/week5/\353\260\260\353\213\254.java" @@ -0,0 +1,82 @@ +import java.util.*; + +class Solution { + + // 그래프에서 사용할 노드 정보 + static class Node implements Comparable { + int to; // 도착한 이웃 마을 번호 + int cost; // 현재까지의 거리(시간) + + Node(int to, int cost) { + this.to = to; + this.cost = cost; + } + + @Override + public int compareTo(Node o) { + return this.cost - o.cost; // 비용 작은 순으로 우선순위 큐 정렬 + } + } + + public int solution(int N, int[][] road, int K) { + // 인접 리스트 그래프 생성 및 초기화. 보기 편하게 1번부터 N번까지 쓸 거라 N+1개 초기화 + List> graph = new ArrayList<>(); + for (int i = 0; i <= N; i++) { + graph.add(new ArrayList<>()); + } + + for (int[] r : road) { + int a = r[0]; + int b = r[1]; + int c = r[2]; + + // a<->b 양방향 도로 정보 저장 (이웃 마을, 이웃 마을까지 걸리는 시간) + graph.get(a).add(new Node(b, c)); + graph.get(b).add(new Node(a, c)); + } + + // 1번 마을에서 i번 마을까지 가는 데 걸리는 최단 시간을 넣을 리스트 생성 + int[] dist = new int[N + 1]; + + // 아직 최단 거리를 모르니 모든 값 '무한대' 로 설정 + Arrays.fill(dist, Integer.MAX_VALUE); + + // 1번 마을에서 자기 자신까지는 0 + dist[1] = 0; + + PriorityQueue pq = new PriorityQueue<>(); + pq.offer(new Node(1, 0)); + + // 탐색해야 할 마을 후보가 남아있는 동안 반복 + while (!pq.isEmpty()) { + Node current = pq.poll(); + int curVillage = current.to; + int curCost = current.cost; + + // 이미 더 짧은 경로로 방문한 적 있으면 스킵 + if (curCost > dist[curVillage]) continue; + + // 현재 마을에서 갈 수 있는 이웃 마을들 확인 + for (Node next : graph.get(curVillage)) { + int nextVillage = next.to; + int nextCost = curCost + next.cost; + + // 더 짧은 경로를 찾았으면 갱신 + if (nextCost < dist[nextVillage]) { + dist[nextVillage] = nextCost; + pq.offer(new Node(nextVillage, nextCost)); + } + } + } + + // K 시간 이하로 도달 가능한 마을 수 세기 + int answer = 0; + for (int i = 1; i <= N; i++) { + if (dist[i] <= K) { + answer++; + } + } + + return answer; + } +} diff --git "a/seahee/week5/\355\230\270\355\205\224_\353\214\200\354\213\244.java" "b/seahee/week5/\355\230\270\355\205\224_\353\214\200\354\213\244.java" new file mode 100644 index 0000000..cb1bccd --- /dev/null +++ "b/seahee/week5/\355\230\270\355\205\224_\353\214\200\354\213\244.java" @@ -0,0 +1,50 @@ +import java.util.*; + +class Solution { + public int solution(String[][] bookTime) { + // 시간을 분 단위로 바꾸고, 청소 시간을 포함해 방 사용 시간을 [start, end+10] 형태로 저장 + // e.g. bookTime[["15:00", "17:00"], ["16:40", "18:20"]] + // -> times[[900,1030], [1000, 1110], ...] + int n = bookTime.length; + int[][] times = new int[n][2]; + + for (int i = 0; i < n; i++) { + int start = toMinutes(bookTime[i][0]); + int end = toMinutes(bookTime[i][1]) + 10; + + times[i][0] = start; + times[i][1] = end; + } + + // 시작 시간 기준으로 오름차순 정렬 + Arrays.sort(times, (a, b) -> a[0] - b[0]); + + // 방이 언제까지 점유 중인지를 저장하는 PQ. 방의 사용 종료 시간이 제일 빠른 게 우선 순위를 가지게 됨. + PriorityQueue pq = new PriorityQueue<>(); + + for (int i = 0; i < n; i++) { + int start = times[i][0]; + int end = times[i][1]; + + // 현재 가장 빨리 비는 방의 시간(pd.peek())이 이번 예약의 시작 시간(start)보다 작거나 같으면 방 재사용 가능 + if (!pq.isEmpty() && pq.peek() <= start) { + pq.poll(); // 그 방은 이번 손님에게 재사용 + } + + // 이번 예약의 end(=퇴실+청소완료 시간)를 방에 배정 + pq.offer(end); + } + + // PQ에 남아 있는 방 개수가 최소 필요한 객실 수 + return pq.size(); + } + + // String인 "HH:MM" → int인 minute으로 변환 + // e.g. 16:40 -> 1000 + private int toMinutes(String time) { + String[] parts = time.split(":"); + int hour = Integer.parseInt(parts[0]); + int min = Integer.parseInt(parts[1]); + return hour * 60 + min; + } +}