Complete the sequence! POJ - 1398 差分方法找数列规律

参考链接:http://rchardx.is-programmer.com/posts/16142.html

vj题目链接:https://vjudge.net/contest/273000#status/kongbursi/L/0/

 

题目给出了一个数列的前若干项,要求推测后面的项。我们很容易想到拉格朗日插值法,但是精度就变成了一个大问题。 这个问题虽然保证了所有的值都是整数,但是并没有保证其多项式的系数也是整数,因此在计算方面存在很大的困难。

除了插值法,求解这种数列问题我们有更好的差分方法,过程中完全不涉及浮点数操作。

比如说,对于1 2 4 7 11 16 22 29 这个数列,我们对于每一项做其和前一项的差,也就是2-1=1, 4-2=2, 7-4=3, ....这样,我们得到一个1阶差分: 1, 2, 3, 4, 5, 6, 7。我们再求得2阶差分是:1, 1, 1, 1, 1, 1。这时,规律已经有些明显了。

 

 

 

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 const int maxn = 100+5;
 5 int n,m,s[maxn][maxn];
 6 int main()
 7 {
 8     int t;
 9     scanf("%d",&t);
10     while (t--)
11     {
12         scanf("%d%d",&n,&m);
13         for (int i = 0; i<n; i++)  //输入
14             scanf("%d",&s[0][i]);
15 
16         for (int i = 1; i<n; i++)  //一直做差,做到只剩下一个数
17             for (int j = 0; i+j<n; j++)
18                 s[i][j] = s[i-1][j+1]-s[i-1][j];
19 
20         for (int i = 1; i<=m; i++)  //在这一个数后面补充m个数,因为我们要求出来后面m个数
21             s[n-1][i] = s[n-1][0];
22 
23         for (int i = n-2; i>=0; i--)   //按照规律递归求出来结果
24             for (int j = 0; j<m; j++)
25                 s[i][n-i+j] = s[i][n-i+j-1]+s[i+1][n-i+j-1];
26 
27         for (int i = 0; i<m-1; i++)
28             printf("%d ",s[0][n+i]);
29         printf("%d\n",s[0][n+m-1]);
30     }
31     return 0;
32 }

 

posted @ 2020-05-13 21:25  kongbursi  阅读(272)  评论(0编辑  收藏  举报