Algorithm
[백준] 선 긋기 2170번 (C++) 라인스와핑
salmon16
2024. 10. 10. 16:36
출처 :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;
}