首先将所有线段按照 (1)左顶点小的在前 (2)左顶点相等则右顶点小的在前 进行排序
注意 (2)必不可少 如果两条线段左顶点相等 选右顶点小的线段可以留更多的空间给后面的线段 有可能放下更多线段 符合我们的目的
再从前向后遍历 每一条线段都会基于"尽可能保留更多不交线段"这一目的来决定留还是不留
用一个变量记录 p 当前保留的这些线段中右顶点的最大位置
分情况讨论
(1)若新来线段的左顶点小于p 则会将之前已经保留的线段替换掉至少一条 并且会使p值增大 不利于放下更多线段 因此这条线段不可取
(2)否则 将当前线段纳入已选线段中
这样做的依据就是 所有线段已按上述规则排序 未遍历的线段中不会再有比当前线段的左顶点还要小的 保证了左顶点的选取是最优的
如果当前这条线段的右顶点小于之前的p值 则更新p 否则不做改动
#include <stdio.h>
#include <algorithm>
using namespace std;
struct node
{
int l;
int r;
};
node line[1001];
int cmp(node n1,node n2)
{
if(n1.l==n2.l)
{
return n1.r<n2.r;
}
else
{
return n1.l<n2.l;
}
}
int main()
{
int n,i,sum,p;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d%d",&line[i].l,&line[i].r);
if(line[i].r<line[i].l)
{
p=line[i].l,line[i].l=line[i].r,line[i].r=p;
}
}
sort(line+1,line+n+1,cmp);
sum=1,p=line[1].r;
for(i=2;i<=n;i++)
{
if(line[i].l<p&&line[i].r<=p)
{
p=line[i].r;
}
else if(line[i].l>=p)
{
p=line[i].r;
sum++;
}
}
printf("%d\n",sum);
return 0;
}