출처 :https://www.acmicpc.net/problem/2170
풀이 방법
라인스와핑 문제로 경우를 나누면 탐색 한 번으로 풀이할 수 있다.
먼저 선을 시작 좌표, 마지막 좌표 기준으로 정렬한다.
그 후 줄이 끊기는 경우와 연장되는 경우를 나누어 풀이하면 된다.
줄이 연장이 되려면 현재 줄의 end보다 다음 줄의 시작 부분의 좌표가 작아야 한다.
그리고 현재 줄의 마지막과 다음 줄의 마지막 중 좌표가 큰 것을 end 좌표로 설정한다.
끊기는 경우는 다음 시작 좌표가 현재 end좌표보가 큰 경우로 이때 끊긴 줄의 길이를 더해주고 start, end값을 초기화해준다.
루프를 다 돈 후 마지막 줄에 대해 더해주는 과정이 필요하다.
입력이 많은 문제이므로 아래 코드를 추가하지 않으면 시간초과가 발생한다.
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
전체 코드
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int N ,ans = 0;
vector<pair<int, int> > lines;
bool cmp(pair<int, int> a, pair<int, int> b) {
if (a.first < b.first) {
return true;
}
else if (a.first == b.first) {
if (a.second < b.second) return true;
else return false;
}
else return false;
}
void sol() {
sort(lines.begin(), lines.end(), cmp);
int start = lines[0].first, end = lines[0].second;
for (int i = 1;i < N;i++) {
if (lines[i].first <= end) { // 줄이 연장되는 경우
end = max(lines[i].second, end);
}
else { // 줄이 끊기는 경우
ans += end - start;
start = lines[i].first;
end = lines[i].second;
}
}
ans += end - start;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> N;
for (int i = 0;i < N;i++) {
int a, b;
cin >> a >> b;
lines.push_back(make_pair(a, b));
}
sol();
cout << ans << endl;
return 0;
}
'Algorithm' 카테고리의 다른 글
[코드트리] 고대 문명 유적 탐사 (c++) 구현 (0) | 2024.10.26 |
---|---|
[백준] 상어 초등학교 21608번 (c++) 구현, 우선순위 큐 정렬 (0) | 2024.10.10 |
[백준] 미세먼지 안녕! 17144번 (c++) 구현, 로컬 배열 선언의 중요, 탐색 순서의 중요 (1) | 2024.10.03 |
[백준] 수 묶기 1744번 (c++) 그리디, 수를 잘 나누기 (0) | 2024.10.02 |
[백준] 경사로 14890 (c++) 구현 (0) | 2024.10.02 |