题意:
有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)); } } }
时间: 2024-11-08 01:57:36