区间覆盖问题
1.不相交区间问题
第一步:将右端点从小到大递增排序
第二步:第一次选择第一个区间T[0].x-T[0].y,然后选择所有不相交区间
#include <iostream>
#include <algorithm>
using namespace std;
typedef struct ds{
int x;
int y;
}DS;
DS T[100+10];
bool cmp(DS s1,DS s2)
{
return s1.y<s2.y;
}
int main()
{
int n;
while(cin>>n)
{
if(n==0) break;
for(int i=0;i<n;i++)
{
cin>>T[i].x>>T[i].y;
}
sort(T,T+n,cmp);
int Y=T[0].y;
int ans=1;//第一次选择x1到y1
for(int i=1;i<n;i++)
{
if(T[i].x>=Y)//循环只选不相交的(开区间>=)
{
Y=T[i].y;
ans++;
}
}
cout<<ans<<endl;
}
return 0;
}
2.区间选点问题
第一步:将右端点从小到大递增排序
第二步:第一个点选取a[0].y,遇到不包含的区间是,选取这个区间的右端点
#include <iostream>
#include <algorithm>
using namespace std;
typedef struct qj{
int x;
int y;
}QJ;
QJ a[100+10];
bool cmp(QJ s1,QJ s2)
{
if(s1.y!=s2.y)
{
return s1.y<s2.y;//y从小到大排序
}
else{
return s1.x>s2.x;//当y相等时x从大到小排序
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i].x>>a[i].y;
}
sort(a,a+n,cmp);
int ans=1;//第一个点是啊a[0].y
int Y=a[0].y;
for(int i=1;i<n;i++)
{
if(a[i].x>Y)
{
Y=a[i].y;//更新右端点
ans++;
}
}
cout<<ans<<endl;
}
return 0;
}
3.完全覆盖问题
第一步:将左端点从小到大递增排序
第二步:先设置已经覆盖的区间为零,再找出所有左端点小于等于当前已经覆 盖到的区域的右端点的区间
第三步:找出其中右端点最大的区间,从而改变覆盖的区域,直到覆盖全部的区域
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
struct qj1{
int a1;
int b1;
}a[10000+10];
struct qj2{
double a2;
double b2;
}b[10000+10];
bool cmp(qj2 s1,qj2 s2)
{
return s1.a2<s2.a2;
}
int main()
{
int N;
cin>>N;
while(N--)
{
int n,w,h;
cin>>n>>w>>h;
for(int i=0;i<n;i++)
{
cin>>a[i].a1>>a[i].b1;
}
int j=0;
for(int i=0;i<n;i++)
{
if(a[i].b1*1.0>h/2.0)
{
b[j].a2=a[i].a1*1.0-sqrt(a[i].b1*a[i].b1*1.0-h*h*1.0/4.0);
if(b[j].a2<0) b[j].a2=0;
b[j].b2=a[i].a1*1.0+sqrt(a[i].b1*a[i].b1*1.0-h*h*1.0/4.0);
if(b[j].b2>w) b[j].b2=w;
j++;
}
}
sort(b,b+j,cmp);
bool flag=1;
int ans=0,i=0;
double maxlen=0,p=0;
while(p<w*1.0)
{
maxlen=0;
for(i;b[i].a2<=p&&i<j;i++)
{
if(b[i].b2-p>=maxlen)
{
maxlen=b[i].b2-p;
}
}
if(!maxlen)
{
flag=0;
break;
}
p+=maxlen;
ans++;
}
if(!flag)
cout<<"0"<<endl;
else cout<<ans<<endl;
}
return 0;
}