L2-018. 多项式A除以B

Posted 给杰瑞一块奶酪~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了L2-018. 多项式A除以B相关的知识,希望对你有一定的参考价值。

这仍然是一道关于A/B的题,只不过A和B都换成了多项式。你需要计算两个多项式相除的商Q和余R,其中R的阶数必须小于B的阶数。

输入格式:

输入分两行,每行给出一个非零多项式,先给出A,再给出B。每行的格式如下:

N e[1] c[1] ... e[N] c[N]

其中N是该多项式非零项的个数,e[i]是第i个非零项的指数,c[i] 是第i个非零项的系数。各项按照指数递减的顺序给出,保证所有指数是各不相同的非负整数,所有系数是非零整数,所有整数在整型范围内。

输出格式:

分两行先后输出商和余,输出格式与输入格式相同,输出的系数保留小数点后1位。同行数字间以1个空格分隔,行首尾不得有多余空格。注意:零多项式是一个特殊多项式,对应输出为“0 0 0.0”。但非零多项式不能输出零系数(包括舍入后为0.0)的项。在样例中,余多项式其实有常数项“-1/27”,但因其舍入后为0.0,故不输出。

输入样例:
4 4 1 2 -3 1 -1 0 -1
3 2 3 1 -2 0 1
输出样例:
3 2 0.3 1 0.2 0 -1.0
1 1 -3.1


最初看到这道题就头疼,做加法乘法的时候就很烦心,现在又来个除法,折磨人啊,想了想数学上也做过这种题,拼凑嘛,我记得当时还是对于分子分母都是多项式的进行化简的一个方法。。说道拼凑就是a/b,只要a找那个存在比b中最高次的指数大,那么就可以拼凑,拿样例来说,a = x^4 - 3x^2 - x - 1,b = 3x^2 - 2x + 1。对于a的第一项指数4比b最高次指数2大,那么商的第一项就是x^4/3x^2 = 0.3x^2,然后用0.3x^2去乘以b的每一项,在a中更新,也就是a要减去b*0.3x^2,更新完以后,a要继续重复以上过程,知道a中最高次比b中最高次低,剩下的就算是余数了,这里用了个map记录a,方便进行更新,b自始至终是不变的。

代码:
#include <iostream>
#include <map>
#include <cmath>
#include <cstdio>
using namespace std;//系数要求保留一位小数,所以绝对值小于0.05都当成0对待
struct poly
{
    int e;
    double c;
}p[10000],ans[10000];
int main()
{
    int n = 0,e = 0,c = 0,m = -1,ant = 0;//m记录a中最高次 e是指数 c是系数 输入都是整数
    map<int,double> q;
    cin>>n;
    for(int i = 0;i < n;i ++)
    {
        cin>>e>>c;
        q[e] = c;
        if(i == 0)m = e;
    }
    cin>>n;
    for(int i = 0;i < n;i ++)
    {
        cin>>p[i].e>>p[i].c;
    }
    while(m >= p[0].e)
    {
        double change = q[m]/p[0].c;//分析中所述的 a中最高次除以b中最高次 系数比
        int diff = m - p[0].e;//指数比
        if(fabs(change) >= 0.05)
        {
            ans[ant].e = diff;
            ans[ant ++].c = change;
            for(int i = 0;i < n;i ++)//change 乘以 b 更新a中的变化
            {
                q[p[i].e + diff] -= change * p[i].c;
            }
        }
        else m --;//一定别忘了m--  不然会超时,太过于马虎  if else语句还是想清楚 写完备一些好光有if没else就容易错误啊。。
        while(m >= p[0].e && fabs(q[m]) < 0.05)
        {
            m --;
        }
    }
    cout<<ant;
    if(!ant)cout<<" 0 0.0";
    for(int i = 0;i < ant;i ++)
        printf(" %d %.1f",ans[i].e,ans[i].c);
    cout<<endl;
    ant = 0;
    while(m >= 0)
    {
        if(fabs(q[m]) >= 0.05)
        {
            ans[ant].e = m;
            ans[ant ++].c = q[m];
        }
        m --;
    }
    cout<<ant;
    if(!ant)cout<<" 0 0.0";
    for(int i = 0;i < ant;i ++)
        printf(" %d %.1f",ans[i].e,ans[i].c);
}

 

以上是关于L2-018. 多项式A除以B的主要内容,如果未能解决你的问题,请参考以下文章

L2-018. 多项式A除以B

团体程序设计天梯赛 L2-018. 多项式A除以B(模拟)

多项式A除以B

1017 A除以B (20分)

PAT乙级 1017. A除以B (20)

辗转相除法求两数的最大公约数的原理是啥?