第三周作业 C题

C题 区间覆盖

题目描述

数轴上有 n (1<=n<=25000)个闭区间 [ai, bi],选择尽量少的区间覆盖一条指定线段 [1, t]( 1<=t<=1,000,000)。
覆盖整点,即(1,2)+(3,4)可以覆盖(1,4)。
不可能办到输出-1

输入

第一行:N和T
第二行至N+1行: 每一行一个闭区间。

输出

选择的区间的数目,不可能办到输出-1

样例输入

3 10
1 7
3 6
6 10

样例输出

2

解题思路

定义一个结构体,来存储这样的区间

struct Node{
 int beg,end;
}node[maxn];

这道题典型贪心算法来解决,分析一下:
我们将这些区间按左端点从小到大排列起来,然后我们开始寻找能覆盖[1,t]的线段,那么这样可以有两个判出条件
1.选择的线段比所有线段多
2.所能到达的最远端是否达到t
如果把这部分思路贪心一下,就可以再变成,当我们在选择下一条线段时,下一条线段的开始一定要比现在已经到达的最远点要小(这样才能完全覆盖)则我们把当前所选线段的远端作为起点继续循环,如果比当前所到达的最远点大时,则发生了断开,不能完全覆盖……这样循环就能得出答案,结合刚才的判出条件就能解决啦
注意事项:[1,2],[3,4]能覆盖[1,4],所以再不断更新开始的头时,注意要加一

#include<iostream>
#include<stdio.h>
#include<algorithm> 
using namespace std;
const int maxn=25010;
struct Node{
 int beg,end;
}node[maxn];
bool cmp(const Node &a,const Node &b)
{
 return a.beg<b.beg;
}
int main()
{ 
 int n,s;
 scanf("%d %d",&n,&s);
// Node node[maxn];
 for(int i=0;i<n;i++)
  scanf("%d %d",&node[i].beg,&node[i].end);
 sort(node,node+n,cmp);
 // start: 第一个没被覆盖的位置
 int ans = 0, start = 1, pos = 0, ok = 0;
 while(start<=s)
 {
  int maxl = 0, k = 0;
  while(pos <= n)
  {
   if(node[pos].beg <= start)
   {
    maxl = max(maxl, node[pos].end);
    pos++;
   }
   else break;
  }
  if(maxl < start)
  {
   ok = 1;
   break;
  }
  start = maxl + 1;
  ans++;
 }
 if(ok==0) cout<<ans;
 else cout<<"-1";
 return 0;
}
发布了20 篇原创文章 · 获赞 0 · 访问量 237

猜你喜欢

转载自blog.csdn.net/GuaXX/article/details/104975725