b_lg_火烧赤壁(讨论完全覆盖/部分覆盖)

给定每个起火部分的起点和终点,请你求出燃烧位置的长度之和。(注:给定的燃烧部分可能会重叠)

思路:模拟

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e4+5;
struct line {
    ll s,e;
} a[N];
bool cmp(line& x, line& y) {
    if (x.s!=y.s) return x.s<y.s;
    return x.e<y.e;
}
int main() {
    std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int n; cin>>n; for (int i=0; i<n; i++) cin>>a[i].s>>a[i].e;
    sort(a,a+n,cmp);
    ll ans=0;
    for (int i=0; i<n; i++) {
        ans+=a[i].e-a[i].s; //-2-(-5)=3,所以负数没影响
        if (i+1<n && a[i].e>a[i+1].s) ans-=a[i].e-a[i+1].s;
    }
    cout<<ans;
    return 0;
}

不知道是不是有什么边界没有处理好30/100,我知道了,原因是因为没有讨论这种情况:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e4+5;
struct line {
    ll s,e;
} a[N];
bool cmp(line& x, line& y) {
    return x.s<y.s;
}
int main() {
    std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	int n; cin>>n; for (int i=0; i<n; i++) cin>>a[i].s>>a[i].e;
	sort(a,a+n,cmp);
	ll s=a[0].s, e=a[0].e, ans=e-s;
	for (int i=1; i<n; i++) {
            if (e>a[i].s && e<a[i].e) { //发现有重叠,但需要检查是否完全覆盖(即&&的后面部分)
                ans+=a[i].e-e;
                s=e, e=a[i].e;
            } else {
                ans+=a[i].e-a[i].s;
                s=a[i].s, e=a[i].e;
            }
	}
    cout<<ans;
    return 0;
}
原文地址:https://www.cnblogs.com/wdt1/p/13926223.html