1. 程式人生 > >1049 數列的片段和 (20 分)

1049 數列的片段和 (20 分)

otto base int lan 分隔 clu iostream baseline uri

給定一個正數數列,我們可以從中截取任意的連續的幾個數,稱為片段。例如,給定數列 { 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。

輸入格式:

輸入第一行給出一個不超過 10?5?? 的正整數 N,表示數列中數的個數,第二行給出 N 個不超過 1.0 的正數,是數列中的數,其間以空格分隔。

輸出格式:

在一行中輸出該序列所有片段包含的數之和,精確到小數點後 2 位。

輸入樣例:

4
0.1 0.2 0.3 0.4

輸出樣例:

5.00

主要思路:

找規律。假設存在N=4的數列,其序列號分別為1,2,3,4,寫出所有片段如下:

(1),(2),(3),(4),(1,2),(2,3),(3,4),(1,2,3),(2,3,4),(1,2,3,4),

則序列號1,2,3,4出現的次數分別為4,6,6,4,可以寫成1*4,2*3,3*2,4*1。

同理若N=5,序列號1~5出現的次數分別為5,8,9,8,5,可以寫成1*5,2*4,3*3,4*2,5*1。

多試幾組數組,可以總結出規律:對於數組中序列號為i的數,其出現次數為i*(N-i+1)。

再探究存在該規律的真正原因。

先觀察一個數,例如,對於N=4的數列中序列號為3的數所在的片段如下:

(起點為1)[(1,2,3),(1,2,3,4)];

(起點為2)[(2,3),(2,3,4)];

(起點為3)[(3),(3,4)],

可以看到片段被分為3類,第i類是以i為起點的片段,每類片段中有終點分別為3,4。

由此推廣,對於長度為N的數列中序列號為i的數,所在的片段可分為i個部分,第i部分起點為i,終點分別為i,i+1,i+2,...,N,共(N-i+1)個,故序列i的出現次數為i*(N-i+1)。

#include<iostream>
using
namespace std; double a[100005]; int main() { int n; double sum=0; cin>>n; for (int i=1;i<=n;i++) { cin>>a[i]; sum+=(double)(n-i+1)*(double)i*a[i];//考慮到浮點數位置對精度的影響,將所有因數轉為浮點數 } printf("%.2lf\n",sum); return 0; }

1049 數列的片段和 (20 分)