二分答案:去寻找石头间最小距离到最大距离,假设给定了一个值,按照这个值去移石头,如果之间的距离小于这个值,则需要把石头移走,合并到下一个值去判断,如果移走的石头数量小于等于题目中给出的,说明我们可以往大的距离去靠近,否则,减小这个距离。这里需要注意最后一个石头到终点的距离也要记上。代码如下
#include<bits/stdc++.h>
#define MAX 1000001
using namespace std;
using gg=long long;
gg L,n,m;
gg arr[MAX];//存储石头之间的距离
gg res=0;
bool check(gg mid)
{
gg num=0;//移走的石头数量
for(int i=0;i<=n;i++)
{
if(arr[i]<mid)
{
gg sum=0;
gg j;
for(j=i;j<=n;j++)//从当前位置去合并前面石头的距离
{
sum+=arr[j];
if(sum>=mid)
{
break;
}
}
num+=(j-i);
i=j;
}
}
if(num<=m)
{
return true;
}
else
{
return false;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cin>>L>>n>>m;
gg x;
gg left=1000000000;
gg right=0;
for(gg i=0;i<n;i++)
{
cin>>arr[i];
if(i==0)x=arr[0];
if(i>0)
{
gg temp=arr[i]-x;
x=arr[i];
arr[i]=temp;
}
left = min(arr[i],left);
right = max(arr[i],right);
}
arr[n]=L-x;//最后一跳不要忘记了。
left = min(arr[n],left);
right = max(arr[n],right);
while(left<=right)
{
gg mid = (left+right)/2;
if(check(mid))
{
res = mid;
left = mid+1;
}
else
{
right=mid-1;
}
}
cout<<res<<"\n";
return 0;
}