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
",num);
    return 0;
}

原文地址:https://www.cnblogs.com/luoxiaoyi/p/13848440.html