POJ-3258 River Hopscotch

来源:互联网 发布:亿次元 淘宝 编辑:程序博客网 时间:2024/05/01 13:30
题意 :牛要到河对岸,在与河岸垂直的一条线上,河中有N块石头,给定河岸宽度L,以及每一块石头离牛所在河岸的距离,
            现在去掉M块石头,要求去掉M块石头后,剩下的石头之间以及石头与河岸的最小距离的最大值。



自己一直在纠结一个问题,为什么这个要用二分做。。。

然后当时想法是能不能找出一个贪心思路,能够直接找出最小值。。然后又想到既然贪心能够直接找出最小值。那么还要二分干嘛。。。。。
有没有贪心找出最小值的方法呢。。。没有。。因为从N个里面减去M个。。枚举绝对超时。。。
所以思维进入一个死胡同


然后看了题解。。


思路是这样的,根据最小距离的性质,加上最后还有N-M个点。进行判断,当最小距离为x时,找出相邻距离大于等于x的N-M个点。。。



这样思路就出来了。。。。

参考题解(致谢)

但是这个题解是有问题的。。。。虽然能AC,但是数据太弱。


比如
1000 5 3
200 400 550 800 810
输出是400
正确是200.。。。。


问题出在,比如有前K个点满足了。。后面剩余的点的距离k还要与最小距离x判断一下。。。k<X也是不行的。。。
问题又来了。。。那么这种贪心,似乎又出现了问题?(其实没问题)。。这样的话,不从前面往后面,从后面往前面行不行?。。细想一下就知道是不行的


代码:

#include <iostream>#include <map>#include <algorithm>#include <cstdio>#include <cstring>#include <cstdlib>#include <vector>#include <queue>#include <stack>#include <functional>#include <set>#include<sstream>#include <cmath>using namespace std;#define pb push_back#define PB pop_back#define bk back()#define fs first#define se second#define INF 1e9+10#define sq(x) (x)*(x)#define eps (1e-10)#define clr(x) memset((x),0,sizeof (x))#define cp(a,b) memcpy((a),(b),sizeof (b))typedef long long ll;typedef unsigned long long ull;typedef pair<int,int> P;const int maxn=50100;int L,N,M;int rock[maxn];bool c(int len){    int last=rock[0];    int cnt,num;    num=0;    for(int i=1;i<=N;i++)    {        if(rock[i]-last>=len)        {            last=rock[i];            num++;            if(num==N-M) break;        }    }    if(num<N-M||L-last<len) return false;    return true;}int main(){   cin>>L>>N>>M;   for(int i=1;i<=N;i++) cin>>rock[i];   rock[N+1]=L;   sort(rock,rock+N+1);   int left,right,mid;   left=0;   right=INF;   while(right-left>1)   {       mid=(right+left)>>1;       if(c(mid)) left=mid;       else       right=mid;   }   cout<<left<<endl;   return 0;}

慢慢对二分加贪心有理解了。。。ORZ


0 0