题意:给出f(x),g(x),h(x)的 (最高次幂+1)的值,以及它们的各项系数,求f(x)*g(x)/h(x)的余数。

  这里多项式的系数只有1或0,因为题目要求:这里多项式的加减法是将系数相加/减后再模2,这样其实也就可以用异或运算来代替加减法。

思路:看代码吧,水题一个,主要在于把除法转化成减法,一次一次减就行。

#include <iostream>
#include <stdio.h>
#include <string.h> using namespace std;
const int maxn=;
//f,g,h存储的是多项式的系数,sum存储的是f*g的系数以及最后余数的系数
int f[maxn],g[maxn],h[maxn],sum[maxn];
int lf,lg,lh,ls;//分别为f,g,h,sum的最高次幂 //比较sum表示的多项式与h表示的多项式的大小
int compare() {
if(ls<lh)
return -;
if(ls>lh)
return ;
for(int i=ls-; i>=; i--) {
if(sum[i]==h[i])
continue;
if(sum[i]>h[i])
return ;
if(sum[i]<h[i])
return -;
}
return ;
}
int main() {
int t,d;
scanf("%d",&t);
while(t--) {
memset(h,,sizeof(h));
memset(sum,,sizeof(sum));
//将f多项式的信息存入f数组
scanf("%d",&d);
lf=d-;
for(int j=lf; j>=; j--) {
scanf("%d",&f[j]);
}
//将g多项式的信息存入g数组
scanf("%d",&d);
lg=d-;
for(int j=lg; j>=; j--) {
scanf("%d",&g[j]);
}
//将h多项式的信息存入h数组
scanf("%d",&d);
lh=d-;
for(int j=lh; j>=; j--) {
scanf("%d",&h[j]);
}
//计算f*g的多项式
ls=lf+lg;
for(int i=lf; i>=; i--) {
for(int j=lg; j>=; j--) {
sum[i+j]=sum[i+j]^(f[i]&g[j]);
}
}
/*
关键是怎么求余数,这里是先判断sum多项式是否大于h多项式,
若大于,则sum减一次h,减去后的信息存入sum中。
再继续判断,直到sum小于h,则此时的sum为余数。
总之,就是把除法改成较简单的减法操作。
*/
while(compare()>=) {
d=ls-lh;
for(int i=ls; i-d>=; i--) {
sum[i]=sum[i]^h[i-d];
}
while(ls && !sum[ls])
ls--;
/*
原先一直WA的代码,在每次更新sum的最高次幂ls时出了错误。
int mark=0;
for(int i=ls; i-d>=0; i--) {
sum[i]=sum[i]^h[i-d]; 下面错误错在这里只判断了i>=d的情况,
有可能当i>=d的时候sum[i]=0,这样求出mark(也就是结果的最高次幂)为0;
但是可能有i<d的时候,有sum[i]=1,那么mark就不为0。 if(sum[i] && !mark) {
mark=i;
} }
ls=mark;
*/ } printf("%d",ls+);
for(int i=ls; i>=; i--) {
printf(" %d",sum[i]);
}
printf("\n");
}
return ;
}
05-08 08:41