概述
1049. 数列的片段和
给定一个正数数列,我们可以从中截取任意的连续的几个数,称为片段。例如,给定数列{0.1, 0.2, 0.3, 0.4},
我们有(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) (0.4) 这10个片段。
给定正整数数列,求出全部片段包含的所有的数之和。如本例中10个片段总和是
0.1 + 0.3 + 0.6 + 1.0 + 0.2 + 0.5 + 0.9 + 0.3 + 0.7 + 0.4 = 5.0。
输入格式:
输入第一行给出一个不超过105的正整数N,表示数列中数的个数,第二行给出N个不超过1.0的正数,是数列中的数,
其间以空格分隔。
输出格式:
在一行中输出该序列所有片段包含的数之和,精确到小数点后2位。
输入样例:
4
0.1 0.2 0.3 0.4
输出样例:
5.00
刚接手题目的时候觉得应该是用dp,dp[i]存放的是从1-i数字相加的和,这样可以用一个双层循环,直接暴力应该
是三层循环,肯定不通过。第一层循环是起点位置,第二层循环是step即每次加和的长度。
#include <stdio.h>
#define MAX 100005
double a[MAX];
double dp[MAX];
int main()
{
int n;
scanf( "%d", &n );
for ( int i = 1 ; i <= n ; ++ i ) {
scanf( "%lf", &a[i] );
dp[i] = a[i] + dp[i-1];
}
double sum = 0;
// 跨度 例: step=0时 计算 a[i]和 step=1时 计算a[i]+--+a[i+1];
for ( int step = 1 ; step <= n ; ++ step ) {
for ( int j = step ; j <= n ; j ++ ) {
sum += dp[j]-dp[j-step];
}
}
printf( "%.2lf", sum );
return 0;
}
想了想可以列举出每个数字在求和的时候出现的次数,由3个数字到4个数字到n个数字的推广,得出n个数中第i个数出现的次数为( i*(n-i+1) )(大家可以自己动手推一下)
就赶紧改了改代码交了。
#include <stdio.h>
#define MAX 100005
double a[MAX];
int main()
{
// 第i个数 需要计算 i*(n-i+1) i=1-n
int n;
double sum = 0;
scanf( "%d", &n );
for ( int i = 1 ; i <= n ; ++ i ) {
scanf( "%lf", &a[i] );
sum += i*( n-i+1 )*a[i];
}
printf( "%.2lf", sum );
return 0;
}
明显可以看到已经优化为O(n)的算法了,就又兴致勃勃的去提交。结果显示3,4答案错误, 一下懵了,报的错误是答案错误而不是超时,说明算法是优化了可能出现了什么
逻辑错误,第一感觉是出现了特殊数据,就赶紧回去读题。完了又感觉没漏掉什么,又想是不是算法出错了,看了看规律确实没错,又想到是不是数据溢出了,但感觉不会啊,
我可是用的double存储的数据,怎么会溢出呢。苦思冥想之际,突然发现 规律中 i*(n-i+1)*a[i], 虽然最后结果是double,但是前面两个整数相乘的时候发生了局部溢出,
就赶紧有换了下表达式的顺序, sum += a[i]*i*(n-i+1), 这样在前两个相乘的时候就已经转换为double,应该不会出问题了。
#include <stdio.h>
#define MAX 100005
double a[MAX];
int main()
{
// 第i个数 需要计算 i*(n-i+1) i=1-n
int n;
double sum = 0;
scanf( "%d", &n );
for ( int i = 1 ; i <= n ; ++ i ) {
scanf( "%lf", &a[i] );
// i*(n-i+1)会溢出 所以先乘double
sum += a[i]*i*( n-i+1 );
}
printf( "%.2lf", sum );
return 0;
}
这是最后一次提交的代码,顺利通过,感觉还是蛮幸运,虽然出了不少错误,但还是很快发现了。
感觉以后在做算法题的时候,要经全力去思考,找最优化的代码,而不是一出现问题就去百度看别人的博客寻求解决办法。
还有就是出现问题了一定不要急,回去认真读题,认真扣字眼,看是不是自己哪里理解错了,是问题就一定有解法,只是代价问题。
最后
以上就是搞怪大炮为你收集整理的1049. 数列的片段和的全部内容,希望文章能够帮你解决1049. 数列的片段和所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复