POJ 3258 River Hopscotch(二分搜索巧妙利用)

题意:

一条长为l(1~1,000,000,000)的河中,有n(1~50,000)块可垫脚的石头(不包括起始点和终点的),

给出它们与起始点的距离rock[i],现在要你移除其中的m块,使得具有最小间距的相邻两块石头之间的距离最大。

思路:

1. 和 POJ 3273 一样的技巧,都是要 求“上(下)界的最小(大)值”问题,以后遇到类似的可以用二分的思路往上面靠;

2. 假设要输出的最终结果为 mid,则根据 mid 的值来确定最少需要去掉多少垫脚石。不断通过二分搜索来锁定最终的值;

3. 解题的时候要注意边界问题,相同符合条件的要尽量往最小(大)上面靠,就如同求:有序递增数组中 x 值的最小(大)下标一样;

 

#include <iostream>

#include <algorithm>

using namespace std;



const int MAXN = 50010;

int n, m, d[MAXN];



int binarysearch(int low, int high) {

    while (low <= high) {

        int mid = (low + high) / 2;

        int count = 0;

        int s = 0, e = 1;

        while (e < n) {

            if (d[e] - d[s] >= mid)

                s = e, e += 1;

            else 

                e += 1, count += 1;

        }

        if (count > m)

            high = mid - 1;

        else

            low = mid + 1;

    }

    return high;

}



int main() {

    int len;

    while (~scanf("%d%d%d", &len, &n, &m)) {

        for (int i = 1; i <= n; i++)

            scanf("%d", &d[i]);

        d[0] = 0, d[n+1] = len;

        n += 2;

        sort(d, d + n);

        int mind = len;

        for (int i = 1; i < n; i++)

            mind = min(mind, d[i] - d[i-1]);

        printf("%d\n", binarysearch(mind, len));

    }

    return 0;

}

你可能感兴趣的:(poj)