http://poj.org/problem?id=3258
二分求最大化最小值
几个注意点:
1、Start放在0里,否则
nums[i] - nums[j] < d
这个判断,如果是默认j=0的话,会有问题,就是,假设第一个石头需要去掉,,是需要标记来处理的,,所以还是,0的位置放0也就是Start
2、二分细节
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int SIZE = 50000+10;
int nums[SIZE];
bool judge(int d, int n, int m) {
int j = 0;
int cnt = 0;
for (int i = 1; i <= n; i++) {
if (nums[i] - nums[j] < d) { //连着几个石头都小于m
cnt ++;
} else {
j = i;
}
}
return cnt <= m;
}
// 二分的前提是, 有解,考虑下再
// at least n-m dis >= d
//int solve(int nums[], int n, int m) {
// int l=0, r = nums[n];
// int mid;
// while( l <= r ) {
// mid = (l+r)/2;
// if (judge(mid, n, m)) {
// l = mid + 1;
// } else {
// r = mid - 1;
// }
// }
//
// return mid;
//}
int solve(int nums[], int n, int m) {
int l=0, r = nums[n]+1;
int mid;
while( l + 1 < r ) {
mid = (l+r)/2;
if (judge(mid, n, m)) {
l = mid ;
} else {
r = mid ;
}
}
return l;
}
int main(int argc, char *argv[]) {
int l, n, m;
while(~scanf("%d%d%d", &l, &n, &m)) {
//int nums[n+1];
nums[0] = 0;
for (int i = 1; i <= n; i++) {
scanf("%d", &nums[i]);
}
++n;
nums[n] = l;
sort(nums, nums+n+1);
printf("%d\n", solve(nums, n, m));
}
return 0;
}