题意
数轴上有 n 个闭区间 [a_i, b_i]。取尽量少的点,使得每个区间内都至少有一个点(不同区间内含的点可以是同一个)
Input
第一行1个整数N(N<=100)
第2~N+1行,每行两个整数a,b(a,b<=100)
Output
一个整数,代表选点的数目
Sample Input-1
2
1 5
4 6
Sample Output-1
1
Sample Input-2
3
1 3
2 5
4 6
Sample Output-2
2
思路
这是一道简单的贪心问题,用最少的点覆盖全部区间。
首先我们需要将这些区间按右断点排序,然后选择第一个区间的右端点,然后将可以覆盖到的所有区间全部删除,接着在从没有覆盖到的区间,将继续执行上述步骤,直到所有区间删除完毕;
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
struct section
{//存储区间 左右端点
int l;
int r;
bool operator < (const section &s) const
{
if(r!=s.r) return r<s.r; //按右端点排序
return l>s.l; //左端点无所谓 逼近同一个右端点可以同时覆盖 右端点相同的全部区间
}
};
vector<section> a; //存储区间
void del(int &p)
{//遍历区间 删除已覆盖点
for(vector<section>::iterator it=a.begin();it!=a.end();)
{
if((*it).l<=p&&(*it).r>=p) it=a.erase(it); //判断点在区间内 然后删除区间
else
{
it++;
}
}
}
int main(int argc, char** argv) {
int n;
scanf("%d",&n);
section b;
for(int i=0;i<n;i++)
{
scanf("%d %d",&b.l,&b.r);
a.push_back(b);
}
sort(a.begin(),a.end()); //按右端点排序
int count=0;
int p;
while(a.size()!=0)
{//遍历 直到区间数位0
p=a[0].r; //选择最顶端的右端点
del(p);
count++;
}
cout<<count;
return 0;
}
总结
这道题是一道小的贪心算法题,如果不明白为什么每次选右端点的可以自己画画图。