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, N. N test cases follow. Each one starts with a line
containing n (0 < n ≤ 50000). The next line will contain the n input 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
题意:这个题,,,读题以为就是求平均数了,而且测试数据还是那样的尽人意。。。
实际上这个题是对每两个连续的数求平均数,,,直到求到只剩一个数字,,,他就是答案
tip:半天没想出来,搜题解了(不搜估计我都不知道自己题意都错了);注意有三点
1.每个数字的使用次数就是C(n-1,k)(k从0到n-1),把他们全加起来就是sum,当然要除以2^n-1;即C(n-1, k)*A[k]/(2^n-1)
2.测试数据会超出范围,咱来取对数处理;即e^(ln C(n-1, k)*A[k]/(2^n-1) )==> e^( ln C(n-1,k) + ln A[k] - (n-1)*ln2 );
3.C组合数,你该咋算,模拟?我用了,超时,有这么个规律 C(n, k) = C(n, k-1)*(n-k+1)/k;但是咋用就看你了,比如下面是
这样子用的::::lnc+=log(n-i+1)-log(i);
好了,看代码吧。。。。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cmath> 5 6 using namespace std; 7 8 int n; 9 double value; 10 11 int main() 12 { 13 int caseNum,num=1; 14 scanf("%d",&caseNum); 15 while(caseNum--) 16 { 17 scanf("%d",&n); 18 n=n-1; 19 double ln2=n*log(2),lnc=0; 20 double ans=0.0; 21 scanf("%lf", &value); 22 23 if(value>0)///C(n,0)的 24 ans+=exp(log(value)+lnc-ln2); 25 else 26 ans-=exp(log(-value)+lnc-ln2); 27 28 for(int i=1;i<=n;++i) 29 { 30 scanf("%lf",&value); 31 lnc+=log(n-i+1)-log(i); 32 if(value>0) 33 ans+=exp(log(value)+lnc-ln2); 34 else 35 ans-=exp(log(-value)+lnc-ln2); 36 } 37 38 printf("Case #%d: %.3lf ",num++,ans); 39 } 40 41 return 0; 42 }