地址:https://www.luogu.com.cn/problem/P2082
解析:
刚开始自己写的代码:
我对L递增排列,L相等按R递增排列。
直接逐个判断,相交,或者不相交。
但让每一个区间只和它前一个区间发生关系,显然是错误的。
比如:
[1,5]
[2,4]
[3,6]
答案应该是6,但是我这个代码输出的是7,原因是第三个区间[3,6]与[2,4]发生了关系,但是[1,5]已经把[2,4]覆盖了。
#include<cstdio>//WAWAWAWAWAWA! #include<stack> #include<map> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int maxn=1e5+20; struct node { ll l,r; }st[maxn]; bool cmp(node a , node b) { if(a.l==b.l) return a.r<b.r; return a.l<b.l; } int main() { // 4 0 20 int n; cin>>n; for(int i=1;i<=n;i++) { cin>>st[i].l>>st[i].r; } ll sum=0; sort(st+1,st+1+n,cmp); sum=st[1].r-st[1].l+1; for(int i=2;i<=n;i++) { if(st[i].r>st[i-1].r) { if(st[i].l>st[i-1].r) sum+=st[i].r-st[i].l+1; else sum+=st[i].r-st[i-1].r; } } cout<<sum<<endl; }
正确的贪心思路:
因为首要排序的是L,所以这个情况下R基本是乱序的。
下一个区间需要算的前提是什么?当然是超出之前所有区间的范围了。
所以可以维护一个最大r,只有当前的区间超越r,才能纳入计算(其实自己算也是这个思想的,脑袋秀逗了)。
同时更新最大的r。
引以为戒~
AC代码:
#include<cstdio> #include<stack> #include<map> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int maxn=1e5+20; struct node { ll l,r; }st[maxn]; bool cmp(node a , node b) { if(a.l==b.l) return a.r<b.r; return a.l<b.l; } int main() { // 4 0 20 int n; cin>>n; for(int i=1;i<=n;i++) { cin>>st[i].l>>st[i].r; } ll sum=0; sort(st+1,st+1+n,cmp); sum=st[1].r-st[1].l+1; ll r=st[1].r; for(int i=2;i<=n;i++) { if(st[i].l>r) { sum+=st[i].r-st[i].l+1; r=st[i].r; } else if(st[i].r>r) { sum+=st[i].r-r; } r=max(r,st[i].r); } cout<<sum<<endl; }