lrj入门经典中介绍的区间覆盖问题,裸的,不过贪心过程稍微复杂一点。
按照书上的过程,先把和要覆盖区间无交集的区间(仅有有一个点也算无交集)删掉,然后根据左值进行排序,这样我们只需扫描一遍数组即可,每次选取坐直小于等于目标区间左值区间,找到最大右值,然后将目标左值改为最大右值,记录路径,并且删除右值小于等于当前目标左值的区间,依次往后即可。
#include <iostream>
#include <algorithm>
using namespace std;
struct coor{
int x,y;
}w[100010];
int ans[100010],anss,size;
bool cmp(struct coor a,struct coor b)
{
return a.x<b.x;
}
int main()
{
int T;
cin>>T;
while(T--){
size=anss=0;
int l=0,r;
cin>>r;
int a,b;
while(cin>>a>>b&&(a||b)){
if(a>b) swap(a,b);
if(b<=l||a>=r) continue;
w[size].x=a;w[size].y=b;
size++;
}
sort(w,w+size,cmp);
for(int i=0;i<size;){
int maxy=-1,maxp=i;
while(i<size&&w[i].x<=l){
if(w[i].y>maxy) {maxy=w[i].y;maxp=i;}
i++;
}
if(maxy==-1) break;
l=maxy;
ans[anss++]=maxp;
if(l>=r) break;
while(i<size&&w[i].y<=l) i++;
}
if(l<r) cout<<0;
else{
cout<<anss<<endl;
for(int i=0;i<anss;i++){
if(i) cout<<endl;
cout<<w[ans[i]].x<<" "<<w[ans[i]].y;
}
}
cout<<endl;
if(T) cout<<endl;
}
return 0;
}