标签:uvalive
题意:
有n个点,每个点高度不一样但一定要在0以上;
而且除了头尾两个点.任意点的高度是前后两个点相加除以2 再减1;
给出最左端的A点高度;求最右端的B点高度最低多少;
思路:
首先由任意点的高度是前后两个点相加除以2 再减1;
我们可以的出;
两个线段的长度差一定是2;
那么我们就可以用等差序列求和来做;
a1 * n + n * (n - 1) * d /2 (因为d = 2,所以d /2可以去掉),a1从0那个点开始上升曲线第一段线段的长度;
现在我们要让左边下降曲线的点尽量多,这样右边上升曲线点就少,B就低;
我们知道A的高度H;
那么a1 * n + n * (n - 1) = H;
那么a1 =( H - n * (n - 1) ) / n;
所以我们要枚举左边的线段有几段;知道有几段,就知道a1是多少,如果n太大会导致a1是负数;所以我们要求a1整数时最大的n;
那么总的线段数 - n就是上升曲线的线段数;并且上升曲线的第一段长度也知道,因为它加上a1要等于2,这样2/2 - 1才会是0;
但是如果算出来下降曲线的线段数就是总线段数,世界输出0;
#include<cstdio>
#include<cstring>
#include<cmath>
const int N = 1005;
double n;
double A;
int main() {
while(scanf("%lf%lf",&n,&A) == 2) {
double i;
double a1;
for(i = n - 1.0; fabs(i - 2) > 1e-9; i -= 1.0) {
if((A - i * (i - 1)) / i > 0) {
a1 = (A - i * (i - 1)) / i;
break;
}
}
if(fabs(i - (n - 1.0)) < 1e-9) {
printf("0.00\n");
}else {
a1 = 2.0 - a1;
n = (n - 1.0 - i);
printf("%.2lf\n",a1 * n + n * (n - 1.0));
}
}
}
标签:uvalive
原文地址:http://blog.csdn.net/yeyeyeguoguo/article/details/45196643