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, N. N 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);
}
}