uva 10883——Supermean

Do you know how to compute the mean (or average) of n numbers? Well, that's not good enough for me. I want the supermean! "What's a supermean," you ask? I'll tell you. List the n given numbers in non-decreasing order. Now compute the average of each pair of adjacent numbers. This will give you n - 1 numbers listed in non-decreasing order. Repeat this process on the new list of numbers until you are left with just one number - the supermean. I tried writing a program to do this, but it's too slow. :-( Can you help me?

Input
The first line of input gives the number of cases, NN test cases follow. Each one starts with a line containing n (0<<b>n<=50000). The next line will contain the ninput numbers, each one between -1000 and 1000, in non-decreasing order.

Output
For each test case, output one line containing "Case #x:" followed by the supermean, rounded to 3 fractional digits.

 

Sample Input

4

1

10.4

2

1.0 2.2

3

1 2 3

5

1 2 3 4 5

 

Sample Output

Case #1: 10.400

Case #2: 1.600

Case #3: 2.000

Case #4: 3.000

 题意:给出n个数字, 要求你求出它们的supermean, supermean的定义是: n个数先两两相邻求平均值, 那么得到n-1个数, 已知循环做这件事直到剩下的数字只有1, 那么这数就是supermean.


思路:该题在刘汝佳的紫书上《入门经典第二版》上有涉及(具体320页),没有书的也可查看我博客中的uva 1635题,和该题类似,比如假设5个数a1,a2,a3,a4,a5,最后退出的结果是a1+4a2+6a3+4a4+a5,聪明的小伙伴或许已经想到杨辉三角,就是杨辉三角,二项式系数c40到c44,然后去求即可,打不了二维表,对于每个n,打一个一维表,最后一步关键的高精度处理,这里采用取对数用double保存;

code:

#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;

const int N=50011;
double f[N];

void my_way(int n) //对于每个n,打一个一维表
{
//f[0]=1;
f[0]=f[n]=0;
for (int i=1;i<=n/2;i++)
f[n-i]=f[i]=f[i-1]+log10(n-i+1)-log10(i); //高精度处理1
}
int main()
{
int n,T,ca=1;
double ans,a;
scanf("%d",&T);
while (T--)
{
scanf("%d",&n);
ans=0;
my_way(n-1);
for (int i=0;i<n;i++)
{
scanf("%lf",&a);
ans+=1.0*pow(10,f[i]-(n-1)*log10(2))*a; //高精度处理2
}
printf("Case #%d: %.3lf\n",ca++,ans);
}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值