# Greedy# Sorting

f855 - 第 3 題 線段覆蓋長度 測資加強版

🔗 前往 ZeroJudge 原題

題目描述

題目要求計算一組線段在數軸上覆蓋的總長度。給定 N 個線段,每個線段由其左端點 L 和右端點 R 定義。線段可能重疊,題目要求計算所有線段覆蓋的總長度,避免重複計算重疊部分。

解題思路

本題可以使用貪心演算法解決。首先,按照線段的左端點升序排序。然後,遍歷排序後的線段,維護一個當前覆蓋區間的右端點 rit。對於每個線段,如果它的左端點大於或等於 rit,則表示它與當前覆蓋區間不重疊,將其加入覆蓋區間,並更新 rit。如果它的右端點大於 rit,則表示它與當前覆蓋區間部分重疊,將覆蓋區間的右端點更新為該線段的右端點。

複雜度分析

  • 時間複雜度: O(N log N) (主要來自排序)
  • 空間複雜度: O(N) (用於儲存線段)

程式碼

#include <iostream>
#include <algorithm>
using namespace std;
struct p{
	int l,r;
};p a[10001];
bool cmp(p x,p y){
	if(x.l<y.l||(x.l==y.l&&x.r<y.r))return 1;
	return 0;
}
int main(){
	cin.tie(0); ios::sync_with_stdio(false);
	int n,sum=0,lit=0,rit=0;
	cin >> n;
	for(int i=0;i<n;++i)
		cin >> a[i].l >> a[i].r;
	sort(a,a+n,cmp);
	for(int i=0;i<n;++i){
		if(a[i].l>=rit){
			lit=a[i].l;
			rit=a[i].r;
			sum+=rit-lit;
		}
		else if(a[i].r>rit){
			sum+=a[i].r-rit;
			rit=a[i].r;
		}
	}
	cout << sum;
}

Discussion