题目描述
从前有一条神奇的项链,为什么说它神奇呢?因为它有两个性质:
- 神奇的项链可以拉成一条线,线上依次是N 个珠子,每个珠子有一个能量值Ei;
- 除了第一个和最后一个珠子,其他珠子都满足Ei=(Ei-1+Ei+1)/2+Di。
由于这条项链很长,我们只能知道其两端珠子的能量值。并且我们知道每个珠子的Di是多少。请聪明的你求出这N 个珠子的能量值分别是多少。
输入
第一行三个整数N、E1、EN,表示珠子个数N,第一个珠子和第N 个珠子的能量值。
第二行N-2 个整数,表示第2 个珠子到第N-1 个珠子的Di。
输出
输出仅一行,N 个整数,表示1 到N 个这N 个珠子各自的能量值Ei。
请放心,数据保证对于任意珠子满足(Ei-1+Ei+1)Mod 2=0
样例输入
Sample Input 1:
4 1 4
0 0
Sample Input 2:
10 1 22
1 2 -3 5 1 4 2 -1
样例输出
Sample Output 1:
1 2 3 4
Sample Output 2:
1 14 25 32 45 48 49 42 31 22
分析
这题用的是一个解方程的方法:
暴力推一下:
**因为e[i]=(e[i-1]+e[i+1])/2+d[i]
所以e[i]=(e[i-1]-d[i])*2-e[i-2]=e[i-1]2-e[i-2]-d[i-1]2
再推一下可得:
e[3]=e[2]*2-e[1]-d[2]*2
e[4]=e[2]*3-e[1]*2-d[2]*4-d[3]*2
得到e[n]=e[2](n-1)-e[1](n-2)-d[2]*(n-2)2-d[3](n-3)*2-…
解e[2]得e[2]=(e[n]+(d[2]*(n-2)2+d[3](n-3)2+…)+e[1](n-2))/(n-1)
再从头列举下去即可。。。
上代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long n,en,e[500001],d[500001];
int main()
{
freopen("fett.in","r",stdin);
freopen("fett.out","w",stdout);
cin>>n>>e[1]>>en;
e[n]=en;
for(int i=2;i<=n-1;i++)
{
cin>>d[i];
en+=d[i]*(n-i)*2;
}
en=(en+e[1]*(n-2))/(n-1);
e[2]=en;
cout<<e[1]<<' '<<e[2]<<' ';
for(int i=2;i<=n;i++)
{
e[i]=(e[i-1]-d[i-1])*2-e[i-2];
cout<<e[i]<<' ';
}
fclose(stdin);
fclose(stdout);
return 0;
}
/*解方程,列举*/