题目什么意思想必大家都已经看懂了,就是要找到一个最大高度使得我可以得到我想要的木材同时又可以将损失最小化,那么就这道题可以给大家引入一个新的概念,二分法。


什么叫二分呢,我做一个很简单的比方,比如我有一组数,从1到10,我要找到数字6,大家第一时间可能想到的就是建立一个数组,然后遍历,就这个例子来说,确实可以,但是如果说我从1到100000000呢,是不是时间复杂度就很高了,是不是就到loga(n)了,所以最优的解法就是运用二分的思想,固定一个左端和右端,求他们的中间值mid,这个例子左端为1,右端为10,mid求出来为5,此时我们将mid和要找的数6做比较,显然mid<6,那么我们是不是就可以缩小我们的寻找范围,将左端的值扩大到我们mid值的下一个,也就是6,再重复之前的算法,此时我们的寻找范围就缩小到了6到10,时间复杂度是不是就大大减小了,这便是二分的中心思想,想必聪明的你已经理解了,那么我们直接上代码


#include<stdio.h>
long long n,m,high[100000010];//设置long long防止爆内存
long long tmp,left,right;//设置左值右值
int main()
{
    scanf("%lld%lld",&n,&m);
    for(long long i=1;i<=n;i++){
        scanf("%lld",&high[i]);
        if(high[i]>right) right=high[i];//将右端赋予值
    }
    while(left<=right){//循环判断,当左值大于右值退出
        int mid=(left+right)/2;//定义中间值
        tmp=0;//定义树木长度初始值
        for(int i=1;i<=n;i++)
            if(high[i]>mid) tmp+=high[i]-mid;//当此轮循环中我们所求的值大于中间值时,将其加入
        if(tmp<m) right=mid-1;//如果累加的值小于我们所需要的值,调整右端值
        else left=mid+1;//同理
    }
    printf("%lld",right);//输出最终值
    return 0;
}

0 条评论

目前还没有评论...