F - 区间覆盖问题
Description
设x1 , x2 ,…… , xn 是实直线上的n 个点。用固定长度的闭区间覆盖这n 个点,至少需要多少个这样的固定长度闭区间?
对于给定的实直线上的n个点和闭区间的长度k,设计解此问题的有效算法,计算覆盖点集的最少区间数,并证明算法的正确性。
Input
输入数据的第一行有2 个正整数n和k(n≤10000,k≤100),表示有n个点,且固定长度闭区间的长度为k。接下来的1 行中,有n个整数,表示n个点在实直线上的坐标(可能相同)。
Output
输出一个整数,表示计算出的最少区间数输出。
Sample
Input
7 3
1 2 3 4 5 -2 6
Output
3
题解:
这道题跟之前那道加油站的题目十分相似,先将输入的点排序,然后从最左边的点开始加线段,覆盖一部分点之后,从新的节点再加线段,直到所有的点都被覆盖为止。
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
int maxn = 10050;
int main(){
/**
*num记录已经用掉的线段数量。
*dis两个点之间的距离。
*t记录当前线段还能覆盖多大范围。
*a记录输入的坐标点。
*/
int i, j, t, num, dis;
int n, k;
int a[maxn];
scanf("%d%d",&n,&k);
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
//冒泡排序,将坐标按升序排序。
for(i=0; i<n-1; i++){
for(j=0; j<n-i-1; j++){
if(a[j]>a[j+1]){
t = a[j];
a[j] = a[j+1];
a[j+1] = t;
}
}
}
num = 1;
dis = k;
/**
*如果两个点的距离还能被当前线段覆盖,那么就下一个点。
*如果两个点的距离不能被当前线段覆盖,那么就再加一条新的线段。
*/
for(i=1; i<n; i++){
if(a[i] - a[i-1] <= dis){
dis -= a[i] - a[i-1];
}
else{
num ++;
dis = k;
}
}
printf("%d\n",num);
return 0;
}