题意
给出n(1–150).
输出两个多项式A,B从常数到最高次的系数,使得对两个多项式求gcd时,恰好经过n步得到结果.
多项式的gcd一步是指(A(x),B(x))变成(B,A mod B)的过程,且当A mod B为0时,视为得到结果B.
A mod B为多项式求余,参见 long division.
要求两个多项式的所有系数都是1,0,-1.前导系数(最高次项系数)为1,度数(最高次)不超过n,第一个多项式的度数大于第二个
分析:
这个题懵逼了好几天,题解愣是没看懂,来学校后在宿舍用笔划拉了好久终于大概是了解了是怎么回事了。
逆推一下GCD的公式:GCD(A,B)=GCD(AX+B,A)。所以可以得到An=An-1*X+An-2。但是题目中有个限制每一位的系数的绝对值不大于1。将GCD变形可以得到GCD(AX+B,A)=GCD(AX-B,A),所以在递推的时候如果系数超过1,那么相减,否则相加。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 6 using namespace std; 7 const int maxn=150+10; 8 int a[maxn][maxn]; 9 int n; 10 11 int main(){ 12 scanf("%d",&n); 13 a[0][0]=1;a[1][1]=1; 14 for(int i=2;i<=n;i++){ 15 for(int j=0;j<=i;j++){ 16 if(j>0) 17 a[i][j]=a[i-1][j-1]; 18 if(j<=i-2){ 19 if(a[i][j]+a[i-2][j]>1) 20 a[i][j]-=a[i-2][j]; 21 else 22 a[i][j]+=a[i-2][j]; 23 } 24 } 25 } 26 printf("%d ",n); 27 for(int i=0;i<=n;i++){ 28 printf("%d ",a[n][i]); 29 } 30 printf(" "); 31 printf("%d ",n-1); 32 for(int i=0;i<n;i++){ 33 printf("%d ",a[n-1][i]); 34 } 35 return 0; 36 }