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;
}
posted @ 2022-02-18 10:48  l_x_y  阅读(27)  评论(0编辑  收藏  举报