【题意】

牛要到河对岸,在与河岸垂直的一条线上,河中有N块石头,给定河岸宽度L,以及每一块石头离牛所在河岸的距离,

现在去掉M块石头,要求去掉M块石头后,剩下的石头之间以及石头与河岸的最小距离的最大值。

【解法】

用二分做,但是开始写了三个版本的二分,全都wa。

无赖看了别人的二分,还是不理解,为什么他们写的就能过。

反复思索后,终于明白了:关键在于题目求的是什么。

做题思想:二分所求的最小距离的最大值mid,记录可以去掉的石头块数cnt(注意:当相邻的石头的距离小于等于mid,就可以去掉),

若cnt > M,h = h - 1 (这里是比较难理解的,也是我纠结挺久的地方),此时,应当回过头来看一下题目求的是什么:

寻找一个长度mid,使得可以去掉M块石头,剩下的石头中,石头间的最小距离为mid

但是cnt记录的是:相邻距离小于等于mid的块数,所以存在这样的一种情况  ---- cnt记录的所有石头中,

有很多块石头间的距离是等于mid,而距离小于mid的石头的块数是小于等于M的,此时,若将h的值减一,

那么h的值就变成一个小于题目所求的答案了。

举个例子就懂了:假设有9块石头,首尾的数都表示河岸。

石头的编号                      1     2     3     4     5        6         7     8      9

石头到河岸的距离     0    4     5     7     9    12      16       19   23     26     28

相邻的距离                  4    1      2     2     3      4        3        3      3       2

假设l = 1,h = 5, M = 4    则mid = 3, 此时去掉的石头的编号为:2,3,5,7,9  cnt = 5

按照程序,h = h - 1 = 4,此时mid = 2,去掉的石头的编号就为:2,4,9     cnt = 3(cnt<M了,

当然也有可能cnt == M,总之就是cnt > M不成立了)

也就是说,之后求得的cnt <= M恒成立, 即题目的答案不在  l 和 h 之间了(这点

之前是让我很费解的地方),更准确地说,答案就是执行这次h-1之前的h值。

若cnt <= M,则l = l + 1,讨论一下:若cnt < M,明显当前的mid小了,l = l + 1;若cnt == M,则去掉cnt块石头后,

剩下的石头的最小值必然是大于mid的,所以进行操作l = l + 1。

然后解决上面遇到的问题,因为h已经小于答案了,而答案就是h+1,之后继续二分cnt <= M恒成立,

l 不断自增,直到跳出循环,因为答案为h+1,我们返回 l 的值,那么while的判断条件就是 l <= h,

当 l 自增到 h + 1时就跳出循环,l == h + 1,正好就是答案。

写了这么多,就是分析了一下二分算法执行的过程,因为以前用的二分while判断条件都是 l < h,看样子以后做二分得多注意了,

稍不注意就会有很多致命的小bug,一定要将对 l 和 h 的操作以及 while的判断条件结合起来考虑,要对二分算法进行灵活的变化,

没有一成不变的模版,具体问题具体分析。

【代码】

 /*
Problem:poj 3258
By:S.B.S.
/*
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstdlib>
#include<iomanip>
#include<cassert>
#include<climits>
#define maxn 10001
#define F(i,j,k) for(int i=j;i<=k;i++)
#define M(a,b) memset(a,b,sizeof(a))
#define FF(i,j,k) for(int i=j;i>=k;i--)
#define inf 0x7fffffff
#define p 23333333333333333
using namespace std;
int l,n,m;
int d[50005];
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline int run(int le,int h,int k)
{
int mid,last,cnt;
while(le<=h)
{
mid=(le+h)>>1;
last=cnt=0;
F(i,1,n+1){
if(mid>=d[i]-d[last]) cnt++;
else last=i;
}
if(cnt>k) h=mid-1;
else le=mid+1;
}
return le;
}
bool cmp(int a,int b)
{
return a<b;
}
int main()
{
std::ios::sync_with_stdio(false);//cout<<setiosflags(ios::fixed)<<setprecision(1)<<y;
// freopen("data.in","r",stdin);
// freopen("data.out","w",stdout);
cin>>l>>n>>m;
d[0]=0;
d[n+1]=l;
F(i,1,n){
cin>>d[i];
}
sort(d+1,d+1+n,cmp);
cout<<run(0,l,m)<<endl;
return 0;
}

poj 3258

poj 3258 River Hopscotch 题解的更多相关文章

  1. 二分搜索 POJ 3258 River Hopscotch

    题目传送门 /* 二分:搜索距离,判断时距离小于d的石头拿掉 */ #include <cstdio> #include <algorithm> #include <cs ...

  2. POJ 3258 River Hopscotch

    River Hopscotch Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 11031   Accepted: 4737 ...

  3. POJ 3258 River Hopscotch (binarysearch)

    River Hopscotch Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5193 Accepted: 2260 Descr ...

  4. POJ 3258 River Hopscotch(二分答案)

    River Hopscotch Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 21939 Accepted: 9081 Desc ...

  5. [ACM] POJ 3258 River Hopscotch (二分,最大化最小值)

    River Hopscotch Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6697   Accepted: 2893 D ...

  6. POJ 3258 River Hopscotch(二分法搜索)

    Description Every year the cows hold an event featuring a peculiar version of hopscotch that involve ...

  7. poj 3258 River Hopscotch(二分+贪心)

    题目:http://poj.org/problem?id=3258 题意: 一条河长度为 L,河的起点(Start)和终点(End)分别有2块石头,S到E的距离就是L. 河中有n块石头,每块石头到S都 ...

  8. POJ 3258 River Hopscotch 二分枚举

    题目:http://poj.org/problem?id=3258 又A一道,睡觉去了.. #include <stdio.h> #include <algorithm> ]; ...

  9. poj 3258 River Hopscotch(二分搜索之最大化最小值)

    Description Every year the cows hold an ≤ L ≤ ,,,). Along the river between the starting and ending ...

随机推荐

  1. 面试题30:最小的K个数

    方法一:利用partition void GetLeastNumbers_Solution1(int* input, int n, int* output, int k) { || k <= ) ...

  2. Asp.net vNext 学习之路(一)

    概述 asp.net vNext 也叫 asp.net 5.0,意思是微软推出的下一个版本的asp.net.可以说是微软对asp.net的一个比较重大的重新设计, asp.net vNext是一 个比 ...

  3. Mybatis异常处理之MySQL Connector Java] will not be managed by Spring

    很长时间没写后台代码有点生疏了,这不今天又出点小插曲,写个文章记录下. 由于要上传点数据到后台,顺手整了个mybatis+springmvc.在保存数据时出现了异常. Creating a new S ...

  4. IndiaHacks 2016 - Online Edition (Div. 1 + Div. 2) E - Bear and Forgotten Tree 2 链表

    E - Bear and Forgotten Tree 2 思路:先不考虑1这个点,求有多少个连通块,每个连通块里有多少个点能和1连,这样就能确定1的度数的上下界. 求连通块用链表维护. #inclu ...

  5. 10.Spark Streaming源码分析:Receiver数据接收全过程详解

    原创文章,转载请注明:转载自 听风居士博客(http://www.cnblogs.com/zhouyf/)   在上一篇中介绍了Receiver的整体架构和设计原理,本篇内容主要介绍Receiver在 ...

  6. idea导入或者检出项目时发现编辑器左侧无法显示项目目录结构

    按下列步骤操作: 1. 关闭IDEA,  2.然后删除项目文件夹下的.idea文件夹 3.重新用IDEA工具打开项目

  7. [BZOJ4032][HEOI2015]最短不公共子串(Trie+DP)

    在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之——被它们虐. 操作一:对A,B分别建SAM,暴力BFS. 操作二:对B建序列自动机或SAM,A在上面暴力匹配. 操作三:对A,B建 ...

  8. 【二分答案】BZOJ2016-Chocolate Eating

    [题目大意] n块巧克力,每次吃可以增加ai点快乐,每天早晨睡觉起来快乐值会减半,求如何使d天睡觉前的最小快乐值最大. [思路] 二分每天的最小快乐值,只要没有达到快乐值就继续吃. 不知道为什么了WA ...

  9. 2017-2018-1 JAVA实验站 冲刺 day07

    2017-2018-1 JAVA实验站 冲刺 day07 各个成员今日完成的任务 小组成员 今日工作 完成进度 张韵琪 写博客.进行工作总结 100% 齐力锋 部分按钮图片.对按钮图片进行ps 100 ...

  10. java23种设计模式之一: 代理模式(动态代理)

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...