POJ - 3258 River Hopscotch(二分搜索:最大化最小值)

来源:互联网 发布:nginx http1.1配置 编辑:程序博客网 时间:2024/04/28 20:01

Link

题意:奶牛们要玩一个在河上跳石子的游戏。一条河上有N个石子,第一颗石子到最后一颗距离为L,要剔除掉M颗石子,使得每个石子间的间隔最大。求这个最大值。

有两种判定方法:

1、贪心法模拟跳石子:排好序,从第一颗开始跳,选择最近的那一颗。如果石子不够了,则return false。

2、也是排序模拟跳石子,但是计算的要剔除的石子数量,如果cnt <= M,则表示还可以尝试继续增加距离,return true, l = mid;

还有两点就是

1、将0跟L这两个石子加进入。

2、d定义的范围要加上2。

#include <iostream>#include <cstdio>#include <algorithm>using namespace std;const int MAX_L = 1e9, MAX_N = 50000;int L, N, M;int d[MAX_N+10];bool C(int x){int last = 0;for(int i = 1; i < N-M+1; i++){int crt = last + 1;while(crt < N+1 && d[crt] - d[last] < x)crt++;if(crt == N+1 || d[N+1] - d[crt] < x)return false;last = crt;}return true;}bool C1(int x){int pre = 0;int cnt = 0;for(int i = 1; i < N+1; i++){if(d[i] - d[pre] < x)cnt++;elsepre = i;}if(cnt <= M)return true;return false;}void solve(){d[N] = 0;d[N+1] = L;sort(d, d+N+2);int l = 0, r = MAX_L;while(r - l > 1){int mid = (l+r)/2;if(C1(mid))l = mid;else r = mid;}printf("%d\n", l);}int main(){freopen("in.txt", "r", stdin);scanf("%d%d%d", &L, &N, &M);for(int i = 0; i < N; i++)scanf("%d", d+i);if(M == N)printf("%d\n", L);elsesolve();return 0;}


0 0
原创粉丝点击