您的位置:首页 > 运维架构

POJ-3258 River Hopscotch

2015-12-27 00:25 288 查看
题意 :牛要到河对岸,在与河岸垂直的一条线上,河中有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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: