给定每个起火部分的起点和终点,请你求出燃烧位置的长度之和。(注:给定的燃烧部分可能会重叠)
思路:模拟
#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;
}