POJ 1060 多项式乘法和除法取余

本文介绍了一种计算多项式乘法及其模运算的方法,通过使用二进制表示来简化加法、减法和乘法的过程,并提供了具体的算法实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Modular multiplication of polynomials
Time Limit: 1000MS        Memory Limit: 10000K
Total Submissions: 4516        Accepted: 2033

Description
Consider polynomials whose coefficients are 0 and 1. Addition of two polynomials is achieved by 'adding' the coefficients for the corresponding powers in the polynomials. The addition of coefficients is performed by addition modulo 2, i.e., (0 + 0) mod 2 = 0, (0 + 1) mod 2 = 1, (1 + 0) mod 2 = 1, and (1 + 1) mod 2 = 0. Hence, it is the same as the exclusive-or operation.

(x^6 + x^4 + x^2 + x + 1) + (x^7 + x + 1) = x^7 + x^6 + x^4 + x^2

Subtraction of two polynomials is done similarly. Since subtraction of coefficients is performed by subtraction modulo 2 which is also the exclusive-or operation, subtraction of polynomials is identical to addition of polynomials.

(x^6 + x^4 + x^2 + x + 1) - (x^7 + x + 1) = x^7 + x^6 + x^4 + x^2

Multiplication of two polynomials is done in the usual way (of course, addition of coefficients is performed by addition modulo 2).

(x^6 + x^4 + x^2 + x + 1) (x^7 + x + 1) = x^13 + x^11 + x^9 + x^8 + x^6 + x^5 + x^4 + x^3 + 1

Multiplication of two polynomials f(x) and g(x) modulo a polynomial h(x) is the remainder of f(x)g(x) divided by h(x).

(x^6 + x^4 + x^2 + x + 1) (x^7 + x + 1) modulo (x^8 + x^4 + x^3 + x + 1) = x^7 + x^6 + 1
The largest exponent of a polynomial is called its degree. For example, the degree of x^7 + x^6 + 1 is 7.

Given three polynomials f(x), g(x), and h(x), you are to write a program that computes f(x)g(x) modulo h(x).
We assume that the degrees of both f(x) and g(x) are less than the degree of h(x). The degree of a polynomial is less than 1000.

Since coefficients of a polynomial are 0 or 1, a polynomial can be represented by d+1 and a bit string of length d+1, where d is the degree of the polynomial and the bit string represents the coefficients of the polynomial. For example, x^7 + x^6 + 1 can be represented by 8 1 1 0 0 0 0 0 1.

Input
The input consists of T test cases. The number of test cases (T) is given in the first line of the input file. Each test case consists of three lines that contain three polynomials f(x), g(x), and h(x), one per line. Each polynomial is represented as described above.

Output
The output should contain the polynomial f(x)g(x) modulo h(x), one per line.

Sample Input

2
7 1 0 1 0 1 1 1
8 1 0 0 0 0 0 1 1
9 1 0 0 0 1 1 0 1 1
10 1 1 0 1 0 0 1 0 0 1
12 1 1 0 1 0 0 1 1 0 0 1 0
15 1 0 1 0 1 1 0 1 1 1 1 1 0 0 1

Sample Output

8 1 1 0 0 0 0 0 1

14 1 1 0 1 1 0 0 1 1 1 0 1 0 0


从后往前插
#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;
const int maxn=2010;
//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 -1;
    if(ls>lh)
        return 1;
    for(int i=ls-1; i>=0; i--) { //如果最高次幂相等,则从高位向下依次比较
        if(sum[i]==h[i])
            continue;
        if(sum[i]>h[i])
            return 1;
        if(sum[i]<h[i])
            return -1;
    }
    return 0;
}
int main() {
    freopen("in.txt","r",stdin);
    int t,d;
    scanf("%d",&t);
    while(t--) {
        memset(h,0,sizeof(h));
        memset(sum,0,sizeof(sum));
        //将f多项式的信息存入f数组
        scanf("%d",&d);
        lf=d-1;
        for(int j=lf; j>=0; j--) {
            scanf("%d",&f[j]);
        }
        //将g多项式的信息存入g数组
        scanf("%d",&d);
        lg=d-1;
        for(int j=lg; j>=0; j--) {
            scanf("%d",&g[j]);
        }
        //将h多项式的信息存入h数组
        scanf("%d",&d);
        lh=d-1;
        for(int j=lh; j>=0; j--) {
            scanf("%d",&h[j]);
        }
        //计算f*g的多项式
        ls=lf+lg;
        for(int i=lf; i>=0; i--) {
            for(int j=lg; j>=0; j--) {
                sum[i+j]=sum[i+j]^(f[i]&g[j]);
            }
        }
        /*
          关键是怎么求余数,这里是先判断sum多项式是否大于h多项式,
          若大于,则sum减一次h,减去后的信息存入sum中。
          再继续判断,直到sum小于h,则此时的sum为余数。
          总之,就是把除法改成较简单的减法操作。
        */
        while(compare()>=0) {
            d=ls-lh;
            for(int i=ls; i-d>=0; 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+1);
        for(int i=ls; i>=0; i--) {
            printf(" %d",sum[i]);
        }
        printf("\n");
    }
    return 0;
}



POJ 3213题目通常涉及矩阵乘法,这是一个经典的算法问题,尤其是在计算机科学竞赛中常见的数学运算部分。矩阵乘法的本质是将两个矩阵相乘,结果是一个新的矩阵,其中每个元素是对应行列元素的乘积之。在Java中,解决这个问题通常会使用嵌套循环来计算每一个位置的值。 以下是解决该问题的一个基本思路简单的Java代码示例: ```java import java.util.Scanner; public class MatrixMultiplication { static int[][] multiply(int[][] a, int[][] b) { int m = a.length; int n = a[0].length; int p = b[0].length; // 创建一个新的矩阵c,用于存储结果 int[][] c = new int[m][p]; for (int i = 0; i < m; i++) { // 遍历第一个矩阵的行 for (int j = 0; j < p; j++) { // 遍历第二个矩阵的列 for (int k = 0; k < n; k++) { // 遍历第一个矩阵的列,作为第二个矩阵的行索引 c[i][j] += a[i][k] * b[k][j]; // 计算并累加结果 } } } return c; } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int rowsA = scanner.nextInt(); int colsB = scanner.nextInt(); int rowsB2 = scanner.nextInt(); int[][] matrixA = new int[rowsA][colsB]; int[][] matrixB = new int[rowsB][rowsB2]; // 读输入矩阵 for (int i = 0; i < rowsA; i++) { for (int j = 0; j < colsB; j++) { matrixA[i][j] = scanner.nextInt(); } } for (int i = 0; i < rowsB; i++) { for (int j = 0; j < rowsB2; j++) { matrixB[i][j] = scanner.nextInt(); } } int[][] result = multiply(matrixA, matrixB); // 打印结果矩阵 for (int[] row : result) { for (int num : row) { System.out.print(num + " "); } System.out.println(); } } } ``` 当你运行这个程序时,它会提示用户输入矩阵A的行数、矩阵B的列数以及矩阵B的大小,然后读矩阵的元素并计算它们的乘积。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值