原题连接:原题链接
题目大意:河流的起点终点各有一块石头,然后这两个石头中间又有N块石头,问去点M块石头后最大的最小距离是多少。(即存在一种去除M块石头的方法,使在该情况下所有石头间的最小距离,在所有的去除M块石头的情况下的最小石头间距中最小)
题目解法:这个题我是通过二分法来求解的,通过对总长L进行二分,然后判断mid(将距离小于mid的左侧石头全部去掉,最后判断剩下的石头是否比目标多),判断后再更新left或者right,因为这里全部是整数,所以直+1/-1就可以了。
这个题目的关键在于,当判断mid时剩下的石头符合条件时,还要继续运算,因为要找最大值,所以又引入了一个变量result,用来储存结果,如果在mid情况下剩下的石头要大于等于目标值,则令结果等于mid,left=mid+1(这里要大于等于的目标是为了求最大的最小值)。
代码部分:
#include<stdio.h>
#include<stdlib.h>
int L,M,N;
int distance[5000];
int judge(int mid)
{
int i,now=0,sum=0;
for(i=0;i<N;i++)
{
if(distance[i]-now<mid)
continue;
else
{
sum++;
now=distance[i];
if(L-distance[i]<mid)
break;
}
}
return sum>=N-M;
}
int compare(const void* a,const void* b)
{
return *(int *)a-*(int *)b;
}
int main()
{
scanf("%d%d%d",&L,&M,&N);
int i;
for(i=0;i<N;i++)
{
scanf("%d",&distance[i]);
}
qosrt(distance,N,sizeof(distance[0]),compare);
int left=0,right=L,result=0,mid=0;
while(left>=right)
{
mid=(left+right)/2;
if(judge(mid))
{
result=mid;
left=mid+1;
}else{
right=mid-1;
}
}
printf("%d\n",result);
return 0;
}
其实二分麻烦的地方就是循环条件的判断以及迭代式子的书写,大体写出来,然后再自己调整就可以了。
努力努力再努力x