UVA10020(最小区间覆盖)
最小 覆盖 区间
2023-09-11 14:14:00 时间
题意:
给你一个区间[0,m]和一些小的区间[l,r]让你选择最少的小区间个数去把整个区间覆盖起来。
思路:
算是比较经典的贪心题目吧(经典于难度没什么对应关系),大体思路可以是这样,我们先把所有的区间按照起点从小到大排序,然后我们定义一个当前覆盖位置pos,初始是0,也就是[0,m]的最左端,然后我们从小区间中找到一个可以覆盖pos点并且右端点最远的一个(记得sum++),然后把最远的这个右端点作为当前的pos,继续找下一个,至于实现,我是自己写的,可能写的不是很简洁,不知道网上有没有简洁点的,如果没有就讲究看下我的吧,具体细节看代码。
#include<stdio.h>
#include<algorithm>
{
int l ,r;
}EDGE;
EDGE edge[N] ,Ans_edge[N];
bool camp(EDGE a, EDGE b)
{
return a.l < b.l;
}
int main ()
{
int m ,nowid ,i ,t ,a ,b;
scanf("%d" ,&t);
while(t--)
{
scanf("%d" ,&m);
nowid = 0;
while(1)
{
scanf("%d %d" ,&a ,&b);
if(!a && !b) break;
if(a > m || b < 0) continue;
++nowid;
edge[nowid].l = a ,edge[nowid].r = b;
}
sort(edge + 1 ,edge + nowid + 1 ,camp);
int Ans = 0 ,pos = 0 ,max = 0 ,mkid = 0;
for(i = 1 ;i <= nowid ;i ++)
{
if(pos > edge[i].r) continue;
if(edge[i].l <= pos)
{
if(max < edge[i].r) {max = edge[i].r ,mkid = i;}
if(i == nowid)
{
if(max < m){Ans = 0 ;break;}
Ans_edge[++Ans] = edge[mkid];
}
}
else
{
if(!max){Ans = 0; break;}
pos = max;
max = 0 ,Ans ++ ,i --;
Ans_edge[Ans] = edge[mkid];
if(pos >= m) break;
}
}
printf("%d\n" ,Ans);
for(i = 1 ;i <= Ans ;i ++)
printf("%d %d\n" ,Ans_edge[i].l ,Ans_edge[i].r);
if(t) printf("\n");
}
return 0;
}
给你一个区间[0,m]和一些小的区间[l,r]让你选择最少的小区间个数去把整个区间覆盖起来。
思路:
算是比较经典的贪心题目吧(经典于难度没什么对应关系),大体思路可以是这样,我们先把所有的区间按照起点从小到大排序,然后我们定义一个当前覆盖位置pos,初始是0,也就是[0,m]的最左端,然后我们从小区间中找到一个可以覆盖pos点并且右端点最远的一个(记得sum++),然后把最远的这个右端点作为当前的pos,继续找下一个,至于实现,我是自己写的,可能写的不是很简洁,不知道网上有没有简洁点的,如果没有就讲究看下我的吧,具体细节看代码。
#include<stdio.h>
#include<algorithm>
#define N 110000
using namespace std;
{
int l ,r;
}EDGE;
EDGE edge[N] ,Ans_edge[N];
bool camp(EDGE a, EDGE b)
{
return a.l < b.l;
}
int main ()
{
int m ,nowid ,i ,t ,a ,b;
scanf("%d" ,&t);
while(t--)
{
scanf("%d" ,&m);
nowid = 0;
while(1)
{
scanf("%d %d" ,&a ,&b);
if(!a && !b) break;
if(a > m || b < 0) continue;
++nowid;
edge[nowid].l = a ,edge[nowid].r = b;
}
sort(edge + 1 ,edge + nowid + 1 ,camp);
int Ans = 0 ,pos = 0 ,max = 0 ,mkid = 0;
for(i = 1 ;i <= nowid ;i ++)
{
if(pos > edge[i].r) continue;
if(edge[i].l <= pos)
{
if(max < edge[i].r) {max = edge[i].r ,mkid = i;}
if(i == nowid)
{
if(max < m){Ans = 0 ;break;}
Ans_edge[++Ans] = edge[mkid];
}
}
else
{
if(!max){Ans = 0; break;}
pos = max;
max = 0 ,Ans ++ ,i --;
Ans_edge[Ans] = edge[mkid];
if(pos >= m) break;
}
}
printf("%d\n" ,Ans);
for(i = 1 ;i <= Ans ;i ++)
printf("%d %d\n" ,Ans_edge[i].l ,Ans_edge[i].r);
if(t) printf("\n");
}
return 0;
}
相关文章
- hdu1960 最小路径覆盖
- hdu 3721 树的最小直径
- POJ 3301 三分(最小覆盖正方形)
- POJ2226 不错的最小顶点覆盖
- POJ2060最小路径覆盖
- POJ1548最小路径覆盖
- TeeChart的最小步长和最大步长
- 【BZOJ2823】[AHOI2012]信号塔(最小圆覆盖)
- 找出一堆数中最小的前K个数
- 【华为OD机试真题 python】等和子数组最小和【2022 Q4 | 100分】
- [matlab] 10.最小覆盖
- 【BZOJ1877】[SDOI2009]晨跑 最小费用最大流
- hihoCoder #1127 : 二分图二·二分图最小点覆盖和最大独立集
- 基于参数化最小互熵(Parametric Minimum Cross Entropy,PMCE)算法的PAPR抑制matlab仿真
- 德研制出世界最小光电信号转换器 直径不到人头发的1/3
- LeetCode 786.第k个最小的素数分数
- 力扣解法汇总1658. 将 x 减到 0 的最小操作数
- 华为OD机试 -求字符串中所有整数的最小和(Java) | 机试题+算法思路+考点+代码解析 【2023】
- nyoj237 游戏高手的烦恼(最小点覆盖)
- hdu1350Taxi Cab Scheme (最小路径覆盖)
- poj 1422 Air Raid (最小路径覆盖)
- [LeetCode] 931. Minimum Falling Path Sum 下降路径最小和
- 最小硬盘实现单原子信息存储 超现有硬盘500倍
- 【bzoj1412】[ZJOI2009]狼和羊的故事 网络流最小割
- leetcode 76. Minimum Window Substring 最小覆盖子串