알고리즘 :: 큰돌 :: Chapter 5 - 라인스위핑 :: 백준 1911번 흙길 보수하기

Embedded June·2023년 8월 28일
0
post-thumbnail

문제

문제 링크

해설

  • 대표적인 라인스위핑 문제 중 하나로, 이 문제(문제링크, 해설링크)와 유사합니다.
  • 웅덩이의 범위가 10억까지이므로 메모리 제한 때문에 절대 좌표상으로 나타낼 수 없습니다.
  • 따라서, 입력받은 물웅덩이를 시작점에 따라 오름차순으로 정렬한 뒤, 시작점부터 끝점까지 널빤지를 하나씩 놓으면서 모든 물웅덩이를 탐색한다면 O(N)에 최적해를 구할 수 있습니다.
  • 널빤지를 최소한으로 사용하기 위해서는
    • 널빤지는 웅덩이의 시작점부터 놓아야합니다.
    • 널빤지의 끝점이 다른 웅덩이와 겹친다면, 계속 놓으면 됩니다.
    • 널빤지의 끝점이 다른 웅덩이와 겹치지 않는다면, 정답에 방금까지 웅덩이를 덮느라 놓았던 널빤지 개수를 증감합니다.
  • 웅덩이에 들어가는 널빤지 개수를 수학적으로 개산하면, ceil(웅덩이 끝점 - 널빤지 끝점) 입니다.
    • 햇갈리실 수 있습니다. 이해합니다.
      • 위에서 말씀드렸지만, 방금 놓은 널빤지가 이번에 새로 시작하는 다른 웅덩이의 시작점을 넘어서 겹칠 수 있습니다.
      • 위 그림에서도 2번째 널빤지가 새로운 웅덩이랑 겹친것을 볼 수 있습니다.
    • 따라서 웅덩이의 길이는 웅덩이의 끝점 ~ 웅덩이의 시작점이 아니라, 웅덩이의 끝점 ~ 널빤지의 끝점입니다.
    • ceil()을 붙인 이유는, 웅덩이를 덮기 위해서는 무조건 소수점을 올림해야 하기 때문입니다. 남는 부분이 있어서는 안 되겠지요?

코드

#include <bits/stdc++.h>
using namespace std;

int main() {
	cin.tie(0)->sync_with_stdio(0);
	
	int N, L;
	cin >> N >> L;
	
	vector<pair<int, int>> vec(N);
	for (int i = 0; i < N; ++i) cin >> vec[i].first >> vec[i].second;
	
	sort(begin(vec), end(vec));
	
	int answer = 0, curPos = vec.front().first;
	for (const auto& pos : vec) {
		if (curPos < pos.first) curPos = pos.first;
		int cnt = ceil(static_cast<double>(pos.second - curPos) / L);
		answer += cnt;
		curPos += cnt * L;
	}
	cout << answer;
}

소스코드 링크

결과

profile
임베디드 시스템 공학자를 지망하는 컴퓨터공학+전자공학 복수전공 학부생입니다. 타인의 피드백을 수용하고 숙고하고 대응하며 자극과 반응 사이의 간격을 늘리며 스스로 반응을 컨트롤 할 수 있는 주도적인 사람이 되는 것이 저의 20대의 목표입니다.

0개의 댓글