码迷,mamicode.com
首页 > 其他好文 > 详细

uvalive2222(等差序列前n项求和)

时间:2015-04-22 18:20:03      阅读:78      评论:0      收藏:0      [点我收藏+]

标签: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));
		}
	}
}



uvalive2222(等差序列前n项求和)

标签:uvalive

原文地址:http://blog.csdn.net/yeyeyeguoguo/article/details/45196643

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!