ACdream1207 群赛C qj的寻找爱情之旅(二分)

来源:互联网 发布:淘宝买家星级怎么算 编辑:程序博客网 时间:2024/04/29 18:57

题目链接:http://115.28.76.232/problem?pid=1207

Problem Description


突然有一天,村子里流传着一个故事,传说爱情正静静躺在这个真爱峡谷的另一端。
傻乎乎的qj一听闻这个消息就喜出望外,倍感高兴,于是开始了他的寻找真爱之旅。
首先第一步就是得找到爱情的位置。
他听村子的老人说过,这个峡谷可以当成由许多点构成的图形,而这些点应该会满足以下规律:
第一个点的高度:      H[1]=A
第i个点的高度:       H[i] = (H[i−1] + H[i+1])/2 − 1, 其中 1 < i < N
而最后一个点的高度:  H[n]=B

对于每个点来说 Hi ≥ 0, 其中1 ≤ i ≤ N
qj目前已经知道第一个点的高度,以及点的数目,请你帮助qj求出最右边B点的最低值,那儿就应该是爱情的所在地。

Input

两个数,分别表示N, A

整数N (3 ≤ N ≤ 1000),实数A (10 ≤ A ≤ 1000) 

Output

输出B,要求保留两位小数哦

Sample Input

692 532.81

Sample Output

446113.34
分析:

首先可以得到公式 h[i]=2*h[i-1]-h[i-2]+2; 但是由于只知道h[1],不知道h[2],所以我试着暴力枚举了一下h[2]  发现 在前一个阶段内 

递推后来肯定有一个h[i]<0,然后,在后一个阶段的时候h[i]一直大于0,而且 h[2]越大h[n]越大;因此在这中间肯定有个临界值

所以[0,h[1]]内二分h[2],然后可以得到最小的h[n];

 代码如下:

#include <iostream>#include <cstdio>#include <cstring>using namespace std;const double eps = 1e-6;const int maxn = 1001;int n;double h[maxn];bool judge(double p){    h[1]=p;    for(int i=2;i<n;i++){        h[i]=2*h[i-1]-h[i-2]+2;        if(h[i]<0)            return 0;    }    return 1;}double bin_search(){    double ans=1000000000;    double l=0,r=h[0];    while(r>l+eps){        double mid=(l+r)/2;        if(judge(mid)){            r=mid;            ans=min(ans,h[n-1]);        }        else l=mid;    }    return ans;}int main(){    while(~scanf("%d%lf",&n,&h[0])){        printf("%.2lf\n",bin_search());    }    return 0;}


0 0