CF22D Segments 题解
题意
有 \(n\) 条线段在一条直线上,问最少找几个点使每条线段上至少有一个点。
分析
一道贪心题。我们先按左端点从小到大排序,记录一下当前需要新取的点的坐标,初始值是第一条线段的右端点的坐标。对于一条新加进来的线段,如果这条线段的右端点比当前点靠左,为了使这条线段上也有一个点,需要把当前点的坐标更新为这条线段的右端点;如果这条线段的左端点比当前点靠右,为了保证全局最优,需要新取一个点,坐标为这条线段的右端点。
代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN=10007;
inline void qread(){}template<class T1,class ...T2>
inline void qread(T1 &IEE,T2&... ls)
{
register T1 x=0;register bool f=false;char ch=getchar();
while(ch<'0') f|=(ch=='-'),ch=getchar();
while(ch>='0') x=(x*10)+(ch^48),ch=getchar();
x=(f?-x:x);IEE=x;qread(ls...);
}
int n;
struct node
{
int l,r;
node(){;}
node(int _l,int _r):l(_l),r(_r){}
bool operator < (const node &o)const{return l<o.l;}
};
vector<node>a;
vector<int>ans;
int main()
{
qread(n);int i,j,t;
for(i=0;i<n;i++)
{
int x,y;qread(x,y);
if(x>y) swap(x,y);
a.push_back(node{x,y});
}
sort(a.begin(),a.end());
int now=a[0].r;
for(i=1;i<n;i++)
{
if(now>a[i].r) now=a[i].r;
else if(a[i].l>now) ans.push_back(now),now=a[i].r;
}
ans.push_back(now);
printf("%d\n",ans.size());
for(auto i:ans) printf("%d ",i);
return 0;
}