Closed baexxbin closed 2 weeks ago
for (int i = 0; i < n; i++) {
// 이미 덮혀있다면 스킵
if (arr[i][1] < prev)
continue;
// 시작 좌표가 덮혀있는지 확인하여 최댓값으로 시작 좌표 계산
prev = Math.max(prev, arr[i][0]);
double len = arr[i][1] - prev; // 덮어야하는 웅덩이의 남은 길이
int cnt = (int) Math.ceil(len / l); // 사용해야하는 판자의 수
total += cnt; // 사용한 판자 수
prev += cnt * l; // 마지막 좌표 기억
}
문제에서는 위치라고 주어져서 양 끝 포함하는 줄 알았는데 시작값만 포함하는 좌표였네요..
1 <= 물웅덩이의 개수 <= 10,000
1 <= 물웅덩이로 덮을 수 있는 길이 <= 1,000,000
0 <= 각 위치 <= 1,000,000,000
반복문을 잘못 쓰면 시간 초과가 발생할 수 있음! 그리디적으로 풀이하여 물웅덩이의 개수 만큼만 시간을 사용할 수 있도록 함
Node
: 물웅덩이의 시작점과 끝점 저장널빤지가 끝점을 넘어가는 경우와 이 경우로 인해 다음 널빤지의 시작점을 넘는 경우 주의하기!
Arrays.sort(nodes, (o1, o2) -> Integer.compare(o1.s, o2.s));
int current = 0, cnt = 0;
for(Node n: nodes) {
if(current < n.s) {
current = n.s;
}
while(current < n.e) {
current += L;
cnt++;
}
}
start
: 놓아야할 널판지 시작점
if (start >= p.e)
int curStart = Math.max(start, p.s)
(끝-시작)/L + (나머지 여부)
curStart + need * L
로 업데이트O(N)으로 완전탐색 가능
N이 작으니깐 완전탐색이나 그리디로 풀면되네요!
N(1 ≤ N ≤ 10,000)
O(N)
TreeMap
을 통해 시작점을 기준으로 오름차순 정렬하며, 시작점이 겹칠 경우 마지막 지점이 더 큰 값을 value 로 지정여분 널판지가 더 필요할 경우 보충한 만큼 길이 추가
result += (end- length)/L; //필수 널판지길이
int reminder = (end- length)%L; //여분 널판지 길이
length = end;
if(reminder != 0){
result++;
length += L - reminder; //여분 널판지를 보충한 만큼 길이 추가
}
N<=10,000, L<=1,000,000 -> O(N
) 이하 가능
정렬
) 물웅덩이를 덮어 나가기 -> 그리디
Arrays.sort(puddles, (a, b) -> Integer.compare(a[0], b[0]));
current >=e
) 널빤지 필요X -> 지나감(continue
)current < s
) -> 물웅덩이 시작 위치부터 덮기