题解 UVA1555 【Garland】(二分)

题面

最近有人问我这个题这么做,光讲几句貌似没什么用,干脆发个题解吧(话说什么有人会来问我这个蒟蒻

题面的意思大概就是说每个点的高度都和旁边2个点有关,整张图没有高度小于0的点,求最后一个点B的最低值

是不是长得像个数学题?所以我们用数学的方法来思考一下Hi怎么得出。

题目中说过,Hi = (H[i−1] + H[i+1])/2-1,也就是已知旁边的2个点,就可以求出中间的点2,因为表达式已知,所以我们可以通过其中2个点求出第3个点。

简单地推一推:设第1个点为a,第2个点为b,第3个点为c,已知a,b。

∵b=(a+c)/2-1;

∴2b+2=a+c

∴2b+2-a=c

这样一来,我们就可以通过前面的点直接推出后面的点了!所以我们就只需要找出使B最低并且每个点都>=0的第2个点就可以了qwq

现在我们已经知道了B点的高度和第2点相关了,但是要求出B的最低的值,该怎么确定第2个点的值呢?

遇到这种在条件中求最值问题,首先想到的肯定是二分。因为二分可以不断地缩小查找范围,最终缩小到不满足条件与满足条件之间,也就是最小的值了。

细节部分直接看代码:

#include<bits/stdc++.h>
using namespace std;
const double mina=1e-6;
int n;
double a,l,r,mid,lp[1010];
bool judge(double x)//每次二分暴力的判断一下是否有点小于0
{
    lp[1]=a;
    lp[2]=x;
    for(int i=3;i<=n;i++)
    {
        lp[i]=2*lp[i-1]-lp[i-2]+2;
        if(lp[i]<0)return false;
    }
    return true;
}
int main()
{
    
    while(scanf("%d%lf",&n,&a)!=EOF)//scanf是有返回值的,返回读入的个数,如果没有的话返回EOF
    {   
        for(int i=0;i<=1009;i++)lp[i]=0.00;
        l=a/2-1;//这里可以优化一下二分的范围,因为这个值刚好使第3个点为0
        r=a;//随便设个高一点的值即可
        while(r-l>mina)//保证精度
        {
            mid=(l+r)/2;
            if(judge(mid)==true)r=mid;//满足的话就可以再小一点
            else l=mid;//不满足的话就增大
        }
        printf("%0.2lf\n",fabs(lp[n]));
        getchar();//读走回车
    }
return 0;
}//看懂了记得点赞QWQ

转载于:https://www.cnblogs.com/Lemir3/p/10327668.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值