题意:给出数轴上的n个区间,每个区间都是连续的int区间。现在要在数轴上任意取一堆元素,构成一个元素集合V,要求每个区间和元素集合V的交集至少有两个不同的元素求集合V最小的元素个数。
解题思路:
考虑到区间之间的重叠性,所以每次都要尽可能地去每个区间靠后的值,才能保证前后两个区间公共的元素最多,其实把握了这个思想后就是个简单的贪心思想了。一开始我是拿每个区间的开始端进行排序,结果WA。。。后面才想到,如果两个区间是包含的关系,那么这样会出现问题。
AC:
#include<iostream>
#include<algorithm>
using namespace std;
typedef class
{
public:
int s,e;
}interval; //间隔(区间)
int cmp(const void* a,const void* b)
{
interval* x=(interval*)a;
interval* y=(interval*)b;
return (x->e) - (y->e); //对区间按末端点排序
}
int main(void)
{
int n; //区间数
while(cin>>n)
{
interval* inter=new interval[n];
for(int i=0;i<n;i++)
cin>>inter[i].s>>inter[i].e;
qsort(inter,n,sizeof(interval),cmp); //对区间按末端点排序
int Selem=inter[0].e-1 , Eelem=inter[0].e; //当前区间所取的两个元素,初始化为第0个区间最后两个元素
int sum=2; //至少取sum个元素才能保证每个区间至少含有其中的2个元素
for(int k=1;k<n;k++)
if(inter[k].s<=Selem) //前一个区间所取的两个元素都在当前区间内
continue; //则当前区间无需取任何元素
else if(inter[k].s<=Eelem) //前一个区间所取的只有一个元素在当前区间内
{
Selem=Eelem;
Eelem=inter[k].e; //按序更新当前区间所取的两个元素:Selem与Eelem
sum++; //Eelem是新取的一个元素
}
else //前一个区间所取的没有一个元素在当前区间内
{
Selem=inter[k].e-1;
Eelem=inter[k].e; //按序更新当前区间所取的两个元素:Selem与Eelem
sum+=2; //Selem与Eelem是新取的两个元素
}
cout<<sum<<endl;
delete inter;
}
return 0;
}