题目:http://poj.org/problem?id=2456
重新练习下二分法,发现还是手速不够
从这道题学到一下几点:
1、线性分几段的方法,看我的Judge()代码;
2、二分的while()最终打印的是down,而不是mid(我代码里写的是ans),或者up,
这么想:跳出循环的时候,假设while里的判断,Judge(ans)==1,那么down是正确解,up不是
Judge(ans)==0,那么ans跟up都不是正确解
综上,打印down才能输出正确解
3、调了好一会二才发现的bug:Judge函数里,if(cnt<c-1)return 0; 注意,cnt==1已经可以有两个牛仓了!!!
贴代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 100000+10;
int n,c;
int dis[MAXN];
int Judge(int s)
{
int cnt=0,last=0,now=0;
while(now<n)
{
//printf("last=%d now=%d cnt=%d s=%d\n",last,now,cnt,s);
now=last+1;
while(now<n && dis[now]-dis[last]<s)now++;
if(now<n)
{
cnt++;
last = now;
}
}
if(cnt<c-1)return 0;/* 此处二逼过*/
else return 1;
}
int main()
{
while(scanf("%d%d",&n,&c)!=EOF)
{
for(int i=0;i<n;i++)
scanf("%d",&dis[i]);
sort(dis,dis+n);
int maxdis=dis[n-1]-dis[0];
int up=maxdis+1,down=0,ans=up;//
//printf("************%d\n",up);
while(up-down>1)
{
ans=(up+down)/2;
if(Judge(ans))down=ans;
else up=ans;
}
printf("%d\n",down);//??ans?
}
}