Given a sequence of positive numbers, a segment is defined to be a consecutive subsequence. For example, given the sequence { 0.1, 0.2, 0.3, 0.4 }, we have 10 segments: (0.1) (0.1, 0.2) (0.1, 0.2, 0.3) (0.1, 0.2, 0.3, 0.4) (0.2) (0.2, 0.3) (0.2, 0.3, 0.4) (0.3) (0.3, 0.4) and (0.4).
Now given a sequence, you are supposed to find the sum of all the numbers in all the segments. For the previous example, the sum of all the 10 segments is 0.1 + 0.3 + 0.6 + 1.0 + 0.2 + 0.5 + 0.9 + 0.3 + 0.7 + 0.4 = 5.0.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N, the size of the sequence which is no more than 105. The next line contains N positive numbers in the sequence, each no more than 1.0, separated by a space.
Output Specification:
For each test case, print in one line the sum of all the numbers in all the segments, accurate up to 2 decimal places.
Sample Input:
4
0.1 0.2 0.3 0.4
Sample Output:
5.00
Thanks to Ruihan Zheng for correcting the test data.
题意分析:
这道题第一反应就是找规律总结公式
先举个例子{1,2,3,4},n=4,(题目里是<1.0的数,我这里用简单整数代替):
(1) | 1 | |||
(2) | 1 | 2 | ||
(3) | 1 | 2 | 3 | |
(4) | 1 | 2 | 3 | 4 |
(5) | 2 | |||
(6) | 2 | 3 | ||
(7) | 2 | 3 | 4 | |
(8) | 3 | |||
(9) | 3 | 4 | ||
(10) | 4 |
每个数轮流做当前分割子序列的首数,其中n=4:
- 第一个数出现 1* 4 次
- 第二个数出现 2*(4-1) 次
- 第三个数出现 3*(4-2) 次
- 第四个数出现 4*(4-3) 次
再举几个例子,这里不再赘述。规律已经很明了了,即每个数出现的次数为:
该数所在位置序号i * (n - i + 1)
但是要注意的是,仅仅按以上的规律直接运行的话,测试点2通不过,后来看了柳神的题解才知道是double的问题:
问题分析:N比较大时,double类型的值多次累加导致的精度误差,因为输入为十进制小数,存储到double中时,计算机内部使用二进制表示,且计算机的字长有限,有的十进制浮点数使用二进制无法精确表示只能无限接近,在字长的限制下不可避免会产生舍入误差,这些细微的误差在N较大时多次累加会产生较大误差,所以建议不要使用double类型进行多次累加的精确计算,而是转为能够精确存储的整型。
解决方法:尝试把输入的double类型的值扩大1000倍后转为long long整型累加,同时使用long long类型保存sum的值,输出时除以1000.0转为浮点型再输出(相当于把小数点向后移动3位后再计算,避免double类型的小数部分存储不精确,多次累加后对结果产生影响)
代码如下:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
double tmp;
long long sum=0;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%lf",&tmp);
sum += (long long)(tmp*1000) * (n - i + 1) * i;
}
printf("%.2f\n", sum/1000.0);
return 0;
}
运行结果如下: