給定一個(gè)正數(shù)數(shù)列,我們可以從中截取任意的連續(xù)的幾個(gè)數(shù),稱為片段。例如,給定數(shù)列 { 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 個(gè)片段。
給定正整數(shù)數(shù)列,求出全部片段包含的所有的數(shù)之和。如本例中 10 個(gè)片段總和是 0.1 + 0.3 + 0.6 + 1.0 + 0.2 + 0.5 + 0.9 + 0.3 + 0.7 + 0.4 = 5.0。
輸入格式:
輸入第一行給出一個(gè)不超過(guò) 10^5的正整數(shù) N,表示數(shù)列中數(shù)的個(gè)數(shù),第二行給出 N 個(gè)不超過(guò) 1.0 的正數(shù),是數(shù)列中的數(shù),其間以空格分隔。
輸出格式:
在一行中輸出該序列所有片段包含的數(shù)之和,精確到小數(shù)點(diǎn)后 2 位。
輸入樣例:
4
0.1 0.2 0.3 0.4
輸出樣例:
5.00
思路:
本題的代碼很短,但是本題的思路卻不是很好想,首先,使用多重循環(huán)的方法是絕對(duì)不可能AC所有測(cè)試點(diǎn),尤其第三個(gè)測(cè)試點(diǎn)。因此就要想別的思路,我們可以觀察一下,不同位置的元素會(huì)出現(xiàn)在多少個(gè)片段中:
假設(shè)有四個(gè)元素,我們會(huì)發(fā)現(xiàn),1號(hào)位置元素總共出現(xiàn)在4個(gè)片段中,2號(hào)位置元素出現(xiàn)在6個(gè)片段中,3號(hào)位置元素出現(xiàn)在6個(gè)片段中,4號(hào)位置元素出現(xiàn)在4個(gè)片段中。這其中是暗含了一定的規(guī)律,因此我們?cè)诩雍偷臅r(shí)候只要知道每一個(gè)元素總共會(huì)出現(xiàn)在幾個(gè)片段中即可進(jìn)行一次循環(huán)的加和操作。
接下來(lái)我們研究一下不同位置元素會(huì)出現(xiàn)的次數(shù)的規(guī)律:
這個(gè)圖我們可以看到第i個(gè)元素跟前面的所有元素可以組成i個(gè)不同的片段。
然后我們?nèi)∑渲幸粋€(gè)片段,跟后面的元素結(jié)合,每一個(gè)片段就可以多產(chǎn)生(N-i)個(gè)片段
因此對(duì)于i位置的元素,一共有i(N-i+1)個(gè)片段
所以在數(shù)組中,我們只需要將i位置的元素乘以這個(gè)次數(shù)然后加和即可,這樣一次循環(huán)就可以完成計(jì)算,代碼如下:
#include<iostream>
using namespace std;
int main()
{
int N;
cin >> N;
double sum = 0,temp;
for (int i = 0; i < N; i++)//由于數(shù)組下標(biāo)是0開(kāi)始的,因此需要轉(zhuǎn)化一下
{
cin >> temp;
sum += temp*(i + 1)*(N - i);
}
printf("%.2f\n", sum);
return 0;
}
代碼:
//1049 數(shù)列的片段和
#include<iostream>
using namespace std;
int main()
{
int N;
cin >> N;
double sum = 0,temp;
for (int i = 0; i < N; i++)
{
cin >> temp;
sum += temp*(i + 1)*(N - i);
}
printf("%.2f\n", sum);
return 0;
}