集训第四周(高效算法设计)D题 (区间覆盖问题)
原题 UVA10020 :http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19688
经典的贪心问题,区间上贪心当然是右区间越右越好了,当然做区间要小于等于当前待覆盖的位置,我们可以用一个变量begin代表当前待覆盖的区间的左值,每一次贪心成功就更新begin的值,然后再进行类似的重复动作
我之前写的版本.两次排序。
#include"iostream"
#include"cstdio"
#include"algorithm"
using namespace std;
const int maxn=100000+10;
struct node
{
int x,y;
}a[maxn],b[maxn];
bool cmp(node a1,node a2)
{
return a1.x<a2.x;
}
bool cm(node a1,node a2)
{
return a1.y>a2.y;
}
int main()
{
int T,t;
cin>>T;
t=T;
while(T--)
{
if(T!=t-1) cout<<endl;
int M,f,l,r,x,a1,b1;
cin>>M;
f=0;
while(cin>>a[f].x>>a[f].y&&(a[f].x||a[f].y))
{
if((a[f].x<0&&a[f].y<0)||(a[f].x>M&&a[f].y>M))
continue;
f++;
}
// cout<<f<<endl;
sort(a,a+f,cmp);
if(a[0].x>0||f==0) cout<<0<<endl;
else
{
sort(a,a+f,cm);
int ff=0,flag=0,sum=0,begi;
begi=0;
while(begi<M)
{
for(int i=0;i<f;i++)
{
if(a[i].x>begi) continue;
if(a[i].y==begi) continue;
begi=a[i].y;flag=1;sum++;b[sum].x=a[i].x;b[sum].y=a[i].y;break;
}
//cout<<begi<<endl;getchar();
if(flag)
{
flag=0;
}
else
{ff=1;