return 0;
}
### 例题:
[[NOIP2005 普及组] 校门外的树 - 洛谷](https://bbs.csdn.net/topics/618545628)
#include<bits/stdc++.h>
using namespace std;
const int maxn=100+20;
struct area{
int l,r;
}a[maxn];
int cmp(area x,area y){
if(x.l==y.l)return x.r<y.r;
return x.l<y.l;
}
int main(){
int ans,la,lb,n,i,L;
scanf(“%d%d”,&L,&n);
for(i=1;i<=n;i++){
scanf(“%d%d”,&a[i].l,&a[i].r);
if(a[i].l>a[i].r)swap(a[i].l,a[i].r);
}
sort(a+1,a+n+1,cmp);
ans=L+1;la=a[1].l;lb=a[1].r;
for(i=2;i<=n;i++){
if(a[i].l>lb){
ans-=lb-la+1;
la=a[i].l;lb=a[i].r;
}
else {
lb=max(lb,a[i].r);
}
}
ans-=lb-la+1;
cout<<ans<<endl;
return 0;
}
### 例题二:
![](https://img-blog.csdnimg.cn/0f2eae2f7709457bbeea5b6d319e7046.png)
### 思路:
>
> 对于输入的每个点,先用勾股定理求出能覆盖住矩形的起点和终点,然后进行一次排序,如果最小的起点和最大的终点都不能超过矩形的长度范围,则必定无解,取出起始点最靠前的点,然后记录下这个点的终点,遍历这个起点到终点范围内的所有其他的点,并挑选其中终点最靠后的那个点作为下一个终点的位置,并且计数器加一,继续向后遍历,如果有区间接不上,则表明无解,成功遍历到矩形最后,则直接输出计数器的值
>
>
>
#include
#include
#include
#include
using namespace std;
const int maxn=10000+10;
struct area{
double l,r;
}a[maxn];
int cmp(area x,area y){
if(x.l==y.l)return x.r<y.r;
else return x.l<y.l;
}
int main(){
int t,n,w,flag,i,tot,x,ans,pos;
double h,tmp,lb,r;
scanf(“%d”,&t);
while(t–){
scanf(“%d%d%lf”,&n,&w,&h);
h=h/2;//矩形的高
tot=0;//共tot个矩形覆盖
for(i=1;i<=n;i++){
scanf(“%d%lf”,&x,&r);
tmp=sqrt(rr-hh);//计算矩形的宽
if(tmp>0){
a[++tot].l=max(0.0,x*1.0-tmp);
a[tot].r=x*1.0+tmp;
}
}
sort(a+1,a+tot+1,cmp);
ans=0;
flag=1;
pos=1;
lb=0;//前pos个区间能覆盖的最大区间
for(;lb<w;){
tmp=0;
for(i=pos;a[i].l<=lb&&i<=tot;i++){
tmp=max(tmp,a[i].r);//左边界在lb以内能覆盖到的最远距离
}
if(tmp>lb){
ans++;//增加一个喷头
lb=tmp;//更新lb
pos=i;//更新pos
}
else {//无法往后覆盖
flag=0;
break;
}
}
if(flag)printf(“%d\n”,ans);else printf(“0\n”);
}
return 0;
}
## 情形2:最大不相交区间数问题
>
> 数轴上有n个区间[ai,bi],要求选择尽量多个区间,使得这些区间两两没有公共点。
>
>
>
贪心策略:
>
> 按照b1<=b2<=b3…的方式排序,然后从前向后遍历,每当遇到可以加入集合的区间,就把它加入集合。(集合代表解的集合)
>
>
>
证明:
>
> 我们对a1,a2……的关系分以下几种情况考虑:
>
>
> 1、a1>a2。 此时区间2包含区间1。这种情况下显然不会选择区间2,因为选择区间1会留下更多的剩余空间。
>
>
> 不仅区间2如此,以后所有区间中只要有一个 i 满足a1 > ai,i 都不要选。
>
>
> 即此种情况下,选择区间1是明智的,与策略一致。
>
>
> 2、排除情况1后,一定有a1<=a2<=a3……。
>
>
>
###
### 例题:
线段覆盖
>
> 已知数轴上0<N<10000条线段。每条线段按照端点Ai和Bi(Ai<>Bi,i=1..N)定义。端点坐标在(-999,999)内,坐标为整数。有些线段可能相交。编程实现删除最少数目的线段,使得余下的任意两条线段不相交。
>
>
>
输入输出格式
### 输入格式:
>
> 第一行为一整数N。接下来有N行,每行包含两个整数 (Ai 和 Bi), 用空格隔开。
>
>
>
### 输出格式:
>
> 整数p,即删除后余下的线段数。
>
>
>
输入输出样例
输入样例#1:
>
> 3
>
>
> 6 3
>
>
> 1 3
>
>
> 2 5
>
>
>
输出样例#1:
>
> 2
>
>
>
### 思路:
>
> 贪心思想,时间复杂度O(nlog(n))
>
>
> 1. 数据给出个端点可能逆序,需判断处理。
>
>
> 2. 排序,将每一个区间按右端点进行递增顺序排列
>
>
> 3.第一个区间必可保留,记录保留区间的最大右边界为pos,遍历区间i,如果a[i].l>pos,则可保留区间增加,并且pos更新为a[i].r。
>
>
>
#include<bits/stdc++.h>
#define MaxInt 100000
using namespace std;
const int maxn=10000+20;
struct line{
int l,r;
}a[maxn];
int n;
int cmp(line x,line y){return x.r<y.r;}
int main(){
int i;
scanf(“%d”,&n);
for(i=1;i<=n;i++){
scanf(“%d%d”,&a[i].l,&a[i].r);
if(a[i].l>a[i].r)swap(a[i].l,a[i].r);
}
sort(a+1,a+n+1,cmp);
int ans=1,pos=a[1].r;
for(i=2;i<=n;i++)
if(a[i].l>=pos){
ans++;
pos=a[i].r;
}
printf(“%d”,ans);
return 0;
}
## 情形3:区间选点问题。
>
> 数轴上有n个闭区间[ai,bi]。取尽量少的点,使得每个区间内都至少有一个点(不同区间内含的点可以是同一个)。
>
>
>
贪心思想:
>
> 先按b从小到大进行排序,再选择b0作为选点pos,如果出现ai>pos,则以bi作为pos,再按照这样的方式迭代。直至所有区间遍历完。
>
>
>
### 描述
>
> 上数学课时,老师给了LYH一些闭区间,让他取尽量少的点,使得每个闭区间内至少有一个点。但是这几天LYH太忙了,你们帮帮他吗?
>
>
>
### 输入
>
> 多组测试数据。
>
>
> 每组数据先输入一个N,表示有N个闭区间(N≤100)。
>
>
> 接下来N行,每行输入两个数a,b(0≤a≤b≤100),表示区间的两个端点。
>
>
>
### 输出
>
> 输出一个整数,表示最少需要找几个点。
>
>
>
### 样例输入
>
> 4
>
>
> 1 5
>
>
> 2 4
>
>
> 1 4
>
>
> 2 3
>
>
> 3
>
>
> 1 2
>
>
> 3 4
>
>
> 5 6
>
>
> 1
>
>
> 2 2
>
>
>
### 样例输出
>
> 1
>
>
> 3
>
>
> 1
>
>
>
#include
#include
#include
#include
using namespace std;
const int maxn=100+10;
struct area{
int l,r;
}a[maxn];
int cmp(area x,area y){
if(x.r==y.r)return x.l<y.l;
else return x.r<y.r;
}
int main(){
int n,i,pos,ans;
while(scanf(“%d”,&n)!=EOF){
for(i=1;i<=n;i++)
scanf(“%d%d”,&a[i].l,&a[i].r);
sort(a+1,a+n+1,cmp);
ans=1;pos=a[1].r;
for(i=2;i<=n;i++){
if(a[i].l>pos){
ans++;
pos=a[i].r;
}
}
printf(“%d\n”,ans);
}
return 0;
}
### 练习:POJ 3485 Highway
### 大意:
>
> X轴上公路从0到L,X轴上下有一些点给出坐标代表村庄,问在公路上最少建几个出口才能使每个村庄到出口的距离不超过D。
>
>
>
### Sample Input
>
> 100
>
>
> 50
>
>
> 3
>
>
> 2 4
>
>
> 50 10
>
>
> 70 30
>
>
>
### Sample Output
>
> 1
>
>
![img](https://img-blog.csdnimg.cn/img_convert/a8424d76b1bda11b01f7a634a578850b.png)
![img](https://img-blog.csdnimg.cn/img_convert/d627b0031f8b4db7850f27dc68dc9fdc.png)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
rn 0;
}
练习:POJ 3485 Highway
大意:
X轴上公路从0到L,X轴上下有一些点给出坐标代表村庄,问在公路上最少建几个出口才能使每个村庄到出口的距离不超过D。
Sample Input
100
50
3
2 4
50 10
70 30
Sample Output
1
[外链图片转存中…(img-4DGXho6H-1714225948670)]
[外链图片转存中…(img-amyehufO-1714225948670)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!