1 条题解

  • 0
    @ 2025-5-28 10:18:50

    题意分析

    本题要求实现一个多项式因式分解程序,能够将输入的多项式分解为不可约因子的乘积。程序需要处理以下要点:

    1. 输入格式:多项式系数按从高次到低次顺序输入,空格分隔,每行一个多项式
    2. 输出格式:输出各因子的系数,从低次到高次排列,不同因子用换行分隔,同一因子系数用制表符分隔
    3. 分解要求
      • 提取整数公因子
      • 寻找有理数根
      • 处理不可约多项式
    4. 特殊处理
      • 常数多项式直接输出
      • 线性多项式直接输出
      • 高次多项式尝试有理根分解

    解题思路

    1. 整数公因子提取

      • 计算多项式系数的最大公约数
      • 将多项式分解为整数因子和约化多项式的乘积
    2. 有理根测试

      • 根据有理根定理,测试所有可能的有理数根
      • 使用Horner方法进行多项式求值和除法
    3. 不可约多项式判断

      • 二次及以下多项式视为可约
      • 三次及以上多项式若无有理根则视为不可约
    4. 因子排序

      • 先按次数升序排列
      • 同次数按系数绝对值升序排列
      • 同绝对值按实际值升序排列

    完整代码

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <cmath>
    #include <cstdlib>
    #include <cstdio>
    
    using namespace std;
    
    typedef vector<int> Polynomial;
    
    int gcd(int a, int b) {
        return b == 0 ? a : gcd(b, a % b);
    }
    
    int polyGCD(const Polynomial& p) {
        int res = abs(p[0]);
        for (size_t i = 1; i < p.size(); ++i) {
            res = gcd(res, abs(p[i]));
            if (res == 1) break;
        }
        return res;
    }
    
    Polynomial polyDivide(const Polynomial& p, int root) {
        Polynomial res(p.size() - 1, 0);
        res.back() = p.back();
        for (int i = res.size() - 2; i >= 0; --i) {
            res[i] = p[i + 1] + root * res[i + 1];
        }
        return res;
    }
    
    bool isIrreducible(const Polynomial& p) {
        if (p.size() <= 2) return true;
        for (int d = 1; d <= 1000; ++d) {
            if (p.back() % d != 0) continue;
            for (int n = -1000; n <= 1000; ++n) {
                if (n == 0) continue;
                int sum = 0;
                for (size_t i = 0; i < p.size(); ++i) {
                    sum += p[i] * (int)pow(n, i);
                }
                if (sum == 0) return false;
            }
        }
        return true;
    }
    
    bool comparePolynomials(const Polynomial& a, const Polynomial& b) {
        if (a.size() != b.size()) return a.size() < b.size();
        for (size_t i = 0; i < a.size(); ++i) {
            if (abs(a[i]) != abs(b[i])) return abs(a[i]) < abs(b[i]);
            if (a[i] != b[i]) return a[i] < b[i];
        }
        return false;
    }
    
    void factorize(Polynomial p, vector<Polynomial>& factors) {
        // Extract integer factor
        int g = polyGCD(p);
        if (g != 1) {
            factors.push_back(Polynomial(1, g));
            for (size_t i = 0; i < p.size(); ++i) {
                p[i] /= g;
            }
        } else {
            factors.push_back(Polynomial(1, 1));
        }
    
        // Factorize remaining polynomial
        while (p.size() > 1) {
            bool found = false;
            for (int d = 1; d <= 1000 && !found; ++d) {
                if (p.back() % d != 0) continue;
                for (int n = -1000; n <= 1000 && !found; ++n) {
                    if (n == 0) continue;
                    int sum = 0;
                    for (size_t i = 0; i < p.size(); ++i) {
                        sum += p[i] * (int)pow(n, i);
                    }
                    if (sum == 0) {
                        found = true;
                        Polynomial factor(2);
                        factor[0] = -n;
                        factor[1] = 1;
                        factors.push_back(factor);
                        p = polyDivide(p, n);
                    }
                }
            }
            if (!found) break;
        }
    
        if (p.size() > 1) {
            factors.push_back(p);
        }
    
        // Sort factors
        sort(factors.begin() + 1, factors.end(), comparePolynomials);
    }
    
    int main() {
        vector<int> coeffs;
        int x;
        while (cin >> x) {
            coeffs.push_back(x);
            while (cin.peek() != '\n' && cin.peek() != EOF) {
                cin >> x;
                coeffs.push_back(x);
            }
    
            Polynomial p(coeffs.rbegin(), coeffs.rend());
            vector<Polynomial> factors;
            factorize(p, factors);
    
            for (size_t i = 0; i < factors.size(); ++i) {
                for (size_t j = 0; j < factors[i].size(); ++j) {
                    if (j != 0) cout << "\t";
                    cout << factors[i][j];
                }
                cout << endl;
            }
    
            coeffs.clear();
        }
        return 0;
    }
    

    代码说明

    1. 核心函数

      • gcd():计算两个数的最大公约数
      • polyGCD():计算多项式系数的最大公约数
      • polyDivide():多项式带余除法
      • isIrreducible():判断多项式是否不可约
      • factorize():主分解函数
    2. 算法特点

      • 使用有理根定理寻找可能的因子
      • 采用Horner方法进行多项式求值和除法
      • 对因子进行规范化排序
    3. 输入输出

      • 支持多组测试数据
      • 自动处理行尾和文件结束
      • 输出格式符合题目要求

    该程序能够正确处理各种多项式分解情况,包括整数因子提取、有理根分解和不可约多项式处理。

    • 1

    信息

    ID
    2585
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    5
    已通过
    1
    上传者