最近有人问我这个题这么做,光讲几句貌似没什么用,干脆发个题解吧(话说什么有人会来问我这个蒟蒻)
题面的意思大概就是说每个点的高度都和旁边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个点的值呢?
遇到这种在条件中求最值问题,首先想到的肯定是二分。因为二分可以不断地缩小查找范围,最终缩小到不满足条件与满足条件之间,也就是最浪小的值了。
细节部分直接看代码:
#includeusing 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