Simple Calculation

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;
}


你可能感兴趣的:(ACM)