二分可做。
只要是能确定答案域的,且可通过验证函数缩小答案域的,基本上都可能可以用二分做。
#include<cstdio>
#include<cstdlib>
int cmp(const void* a,const void* b)
{
return *(int*)a-*(int*)b;
}
bool check(int len,int n,int m,int* stone,int temp)
{
int go=0,k=0,times=0;
while(go<len)
{
//printf("go=%d len=%d stone[%d]=%d times=%d\n",go,len,k,stone[k],times);
while(go+temp>=stone[k]&&k<n+1) k++;
if(go+temp>=len×<m) return true;
else if(go+temp>=stone[k-1]&&go<stone[k-1]×<m) {go=stone[k-1]; times++;}
else return false;
}
}
int slove(int len,int n,int m,int* stone)
{
int left=0,right=len;
while(left<right)
{
int mid=(left+right)/2;
//printf("mid=%d\n",mid);
if(check(len,n,m,stone,mid)) right=mid;
else left=mid+1;
//printf("left=%d right=%d\n",left,right);
}
return right;
}
int main()
{
int l,n,m;
while(scanf("%d%d%d",&l,&n,&m)!=EOF)
{
int stone[n+1];
for(int i=0;i<n;i++)
scanf("%d",&stone[i]);
stone[n]=l;
qsort(stone,n,sizeof(stone[0]),cmp);
printf("%d\n",slove(l,n,m,stone));
}
return 0;
}