
这道题在洛谷已经有很多人使用了二分法,我根据洛谷第一篇题解(我觉得他的代码有一点点问题)写出了我自己的理解
先从有序排序
我们从最大的开始砍,从i到i-1,我们可以让比a[i]这棵树大的数全部再次砍去a[i+1]-a[i]的高度
也就是sum+=(n-i)*(a[i+1]-a[i]);这样可以有效节约运算时间
如果sum>m我们就要考虑是不是砍多了,所以我们就退回到a[i+1]去遍历输出,直到符合条件
代码如下
#include "bits/stdc++.h"
using namespace std;
const int N=1e6+5;
long long a[N];
long long sum=0;
int main(){
long long m,n;cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+1+n);
for (int i=n-1;i >=1;i--) {
sum+=(n-i)*(a[i+1]-a[i]);
if(sum==m){
cout<<a[i];
break;
}
else if(sum>m){
sum-=(n-i)*(a[i+1]-a[i]);
while(a[i]<=a[i+1]){
sum+=(n-i);
a[i+1]--;
if(sum>=m)break;
}
cout<<a[i+1];
break;
}
}
return 0;
}
本文介绍了如何运用二分法解决一道编程题,作者首先对输入数据进行排序,然后从最大值开始削减,通过计算累计差值来判断是否超过给定限制。当超过限制时,代码会回溯并调整,以找到满足条件的答案。
1703

被折叠的 条评论
为什么被折叠?



