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时:
a1=(a0+a2)/2-c1;
a2=(a1+a3)/2-c2;
a3=(a2+a4)/2-c3;
...
a(n-1)=(a(n-1)+a(n))/2-c(n-1);
a(n)=(a(n-1)+a(n+1))/2-c(n);
然后叠加:
a1+a(n)=a0/2+a1/2+a(n)/2+a(n+1)/2-(c1+c2+...+c(n));
a1+a(n-1)=a0/2+a1/2+a(n-1)/2+a(n)/2-(c1+c2+...c(n-1));
...
a1+a2=a0/2+a1/2+a2/2+a3/2-(c1+c2);
注意最后一个特殊情况:
a1+a1=a0+a2-2*c1;
最后叠加得:
(n+1)*a1=n*a0+a(n+1)-2*((c1+c2+...+c(n))+...+(c1+c2)+c1);
最后解出a1即可。
二.
根据原式可以得
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;
}