문제
풀이
정렬, 스위핑 문제이다.
- 현재 긋고 있는 선의 시작을 start, 끝을 end라고 하자.
- 선을 긋고 있을 때, 어떤 상황에서 다음 선을 한번에 그을 수 있을까?
- 만약 다음으로 그을 선의 시작이 end보다 작다면 그 선분은 한번에 그을 수 있다.
- 그리고 해당 선분의 끝이 end보다 크다면 해당 선분의 끝까지 한번에 그을 수 있다.
- 다음으로 그을 선의 시작이 end보다 크다면 그 선분은 한번에 그을 수 없으므로, 끊어서 그려야 한다.
- 선을 끊었다면, 다음으로 그을 선이 새로운 start와 end를 가진다.
코드
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<pair<int, int>> lines;
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(NULL);
cout.tie(NULL);
int N;
cin >> N;
for (int i = 0; i < N; ++i)
{
int start, end;
cin >> start >> end;
lines.push_back(make_pair(start, end));
}
// 선들을 정렬한다.
sort(lines.begin(), lines.end());
int answer = 0;
int start = lines[0].first;
int end = lines[0].second;
for (int i = 1; i < lines.size(); ++i)
{
// 검사하는 선의 시작이 현재 긋는 선의 끝보다 작거나 같은 값이라면 한번에 그을 수 있다.
if (lines[i].first <= end)
{
// 검사하는 선의 끝이 현재 긋는 선의 끝보다 크다면 검사하는 선의 끝까지 긋는다.
if (end < lines[i].second)
{
end = lines[i].second;
}
}
// 검사하는 선의 시작이 현재 긋는 선의 끝보다 크다면 새로 선을 그어야 한다.
else
{
// 현재 긋고 있는 선의 길이를 answer에 추가하고
// 새로운 선을 긋는다.
answer += (end - start);
start = lines[i].first;
end = lines[i].second;
}
}
// 마지막 선은 위의 반복문에서 들어가지 않으므로 따로 추가한다.
answer += (end - start);
cout << answer;
return 0;
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준][C++] 17609: 회문 (0) | 2023.11.15 |
---|---|
[백준][C++] 9527: 1의 개수 세기 (0) | 2023.11.14 |
[백준][C++] 17135: 캐슬 디펜스 (1) | 2023.11.12 |
[백준][C++] 14890: 경사로 (0) | 2023.11.10 |
[백준][C++] 11559: Puyo Puyo (1) | 2023.11.09 |