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;
}
posted @ 2013-04-20 15:54  kedebug  阅读(580)  评论(0编辑  收藏  举报