题意:给你一串数字,问这串数字符合f[n] = a*f[n-1],f[n] = a*f[n-1]+b*f[n-2],f[n] = a*f[n-1]+b*f[n-2]+c*f[n-3]这几个方程中的哪个,然后要你给出第n+1项,如果符合多个方程,项数小的优先(第一个方程优先)。
解法:这题我先处理看是否满足f[n] = a*f[n-1]的形式,如果不满足,则用高斯消元借出两项和三项的情况的a,b,c,比如第二个方程,f[3] = a*f[2]+b*f[1],f[4] = a*f[3]+b*f[2],两个方程两个未知量,用高斯消元解出a,b,这里可能不是整数,我将他们加了个0.5取下整,居然对了。后来看那场比赛没一个人是用的高斯消元,所以不知道这样是否正确,有看出来端倪的欢迎评论告诉我。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 4 int f[];
typedef double Matrix[N][N];
int x,y,z; void gauss_elimination(Matrix A,int n)
{
int i,j,k,r;
for(i=;i<n;i++)
{
//选一行r并与i行交换
r = i;
for(j=i+;j<n;j++)
if(fabs(A[j][i]) > fabs(A[r][i]))
r = j;
if(r != i)
{
for(j=;j<=n;j++)
swap(A[r][j],A[i][j]);
}
//与第i+1~n行进行消元
for(k=i+;k<n;k++)
{
double f = A[k][i]/A[i][i]; //为了让A[k][i] = 0,第i行乘以的倍数
for(j=i;j<=n;j++)
A[k][j] -= f*A[i][j];
}
}
//回代
for(i=n-;i>=;i--)
{
for(j=i+;j<n;j++)
A[i][n] -= A[j][n]*A[i][j];
A[i][n] /= A[i][i];
}
x = (int)floor(A[][n]+0.5);
y = (int)floor(A[][n]+0.5);
if(n == )
z = (int)floor(A[][n]+0.5);
} int main()
{
int t,n,i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
memset(f,,sizeof(f));
for(i=;i<=n;i++)
scanf("%d",&f[i]);
int ans = Mod;
int a1,a2,a3;
int flag;
if((f[] == && f[] == ) || f[]%f[] == )
{
if(f[] == && f[] == )
a1 = ;
else
a1 = f[]/f[];
flag = ;
for(i=;i<=n;i++)
{
if(f[i] != a1*f[i-])
flag = ;
}
if(flag)
ans = a1*f[n];
}
if(ans != Mod)
{
printf("%d\n",ans);
continue;
}
Matrix A;
A[][] = A[][] = f[];
A[][] = f[];
A[][] = f[];
A[][] = f[];
A[][] = f[];
gauss_elimination(A,);
flag = ;
for(i=;i<=n;i++)
{
if(f[i] != x*f[i-]+y*f[i-])
flag = ;
}
if(flag)
ans = x*f[n]+y*f[n-];
if(ans != Mod)
{
printf("%d\n",ans);
continue;
}
A[][] = A[][] = A[][] = f[];
A[][] = A[][] = f[];
A[][] = f[];
A[][] = A[][] = f[];
A[][] = f[];
A[][] = f[];
A[][] = f[];
A[][] = f[];
gauss_elimination(A,);
//printf("%d %d %d\n",x,y,z);
ans = x*f[n]+y*f[n-]+z*f[n-];
if(ans != Mod)
printf("%d\n",ans);
}
return ;
}