[Java] 백준 1911 흙길 보수하기

hyunnzl·2025년 1월 24일

백준

목록 보기
41/116
post-thumbnail

https://www.acmicpc.net/problem/1911

난이도

골드5

문제

어젯밤 겨울 캠프 장소에서 월드 본원까지 이어지는, 흙으로 된 비밀길 위에 폭우가 내려서 N(1 ≤ N ≤ 10,000)개의 물웅덩이가 생겼다. 월드학원은 물웅덩이를 덮을 수 있는 길이가 L(1 ≤ L ≤ 1,000,000)인 널빤지들을 충분히 가지고 있어서, 이들로 다리를 만들어 물웅덩이들을 모두 덮으려고 한다. 물웅덩이들의 위치와 크기에 대한 정보가 주어질 때, 모든 물웅덩이들을 덮기 위해 필요한 널빤지들의 최소 개수를 구하여라.

입력

첫째 줄에 두 정수 N과 L이 들어온다.

둘째 줄부터 N+1번째 줄까지 총 N개의 줄에 각각의 웅덩이들의 정보가 주어진다. 웅덩이의 정보는 웅덩이의 시작 위치와 끝 위치로 이루어진다. 각 위치는 0 이상 1,000,000,000 이하의 정수이다. 입력으로 주어지는 웅덩이는 겹치지 않는다.

출력

첫째 줄에 모든 물웅덩이들을 덮기 위해 필요한 널빤지들의 최소 개수를 출력한다.

내 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

class Main {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		int N = Integer.parseInt(st.nextToken());
		int L = Integer.parseInt(st.nextToken());

		PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> {
			if (a[0] != b[0]) {
				return Integer.compare(a[0], b[0]);
			}
			return Integer.compare(a[1], b[1]);
		});
		
		for (int i = 0; i < N; i++) {
			st = new StringTokenizer(br.readLine());
			int start = Integer.parseInt(st.nextToken());
			int end = Integer.parseInt(st.nextToken());
			pq.add(new int[] { start, end });
		}

		int ans = 0;
		int last = 0;
		
		while (!pq.isEmpty()) {
            int[] now = pq.poll();
            int start = Math.max(last, now[0]); // 이미 덮은 구간은 제외
            int end = now[1];
            
            // 현재 물웅덩이를 덮기 위해 필요한 널빤지 개수 계산
            while (start < end) {
                start += L; // 널빤지를 배치
                ans++;
            }
            last = start; // 마지막으로 덮은 구간 업데이트
		}
		System.out.println(ans);
	}
}

PriorityQueue로 웅덩이를 정렬하면서 꺼낼 수 있도록 입력을 받았다.

그 후에 널빤지가 겹쳐서 깔릴 수 있기 때문에 널빤지를 깔아 준 마지막 위치를 기억해야 한다.

큐에서 하나씩 꺼낼 때마다 이미 깔아진 곳이라면 넘어가야하기 때문에, Math.maxstart, end를 지정해서 while문을 그냥 패스할 수도 있게 구현했다.

그리고 startL만큼 더하면서 end 위치를 넘을때까지 while문을 돌고나서 마지막에 laststart로 업데이트 하면 된다.


0개의 댓글