description |
有一个包含n+2个元素的序列(a[0],a[1],…,a[n+1])。我们知道,对于任意的i(i=1,2,...,n),满足a[i]=(a[i-1]+a[i+1])/2-c[i]。给定a[0],a[n+1],c[0],c[1],...c[n],你的任务是写一个程序求出a[1]。 |
input |
输入包含三行。 第一行包括一个整数n(1≤n≤3000)。 第二行包含两个浮点数a[0]和a[n+1]。 第三行包括n个浮点数,即c[1],c[2],...,c[n](保证-100≤c[i]≤100,-3000≤a[i]≤3000)。 |
output |
输出包含一行,即数字a[1](保留两位小数)。 |
sample_input |
1 50.50 25.50 10.15 |
sample_output |
27.85 |
此题关键在于对公式的变形与推导,下面附上几种方法:
一..当n=1或者n=0的时候直接输出就行了,当n>1时:
二.
根据原式可以得
a[n+1]-a[n]=a[n]-a[n-1]+2*c[n]①
设S[n]=c[1]+c[2]+…+c[n]
对①式叠加相消可以得到a[n+1]-a[1]=a[n]-a[0]+2*S[n]
整理得a[n+1]-a[n]=a[1]-a[0]+2*S[n]②
对②式叠加相消可得到a[n+1]-a[1]=n*(a[1]-a[0])+2*(S[1]+S[2]+…+S[n])
即可算出a[1]的大小。
由于第二种方法代码比较简单,故附上第二种方法代码:
(推导公式到竟然连数组都不需要开,看到这种方法觉得有些人的思维简直了!!)
#include <iostream> #include <stdio.h> using namespace std; int main() { double c,a0,an1; int n; while(cin>>n>>a0>>an1) { double s=0,su=0; for(int i=0;i<n;i++) { cin>>c; s+=c; su+=s; } double a1=(an1 + n * a0 - 2 * su) / (n + 1.0); printf("%.2f\n",a1); } return 0; }