PAT--L2-018 多项式A除以B

版权声明:大佬们转载时别忘了我哦!!! https://blog.csdn.net/sun9979/article/details/87868689

题目描述:
这仍然是一道关于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

代码如下:

#include<iostream>
#include<cmath>
using namespace std;
double c1[4000]={0},c2[4000]={0},c3[4000]={0};
int num(double c[],int maxx)
{
    int cnt=0;
    for(int i=0;i<=maxx;i++)
        if(abs(c[i])+0.05>=0.1) cnt++;
    return cnt;
}
void print(double c[],int maxx)
{
    printf("%d",num(c,maxx));
    if(num(c,maxx)==0) printf(" 0 0.0");
    for(int i=maxx;i>=0;i--)
        if(abs(c[i])+0.05>=0.1) printf(" %d %.1f",i,c[i]);
}
int main()
{
    int n1,n2,e,max1=-1,max2=-1;
    scanf("%d",&n1);
    for(int i=0;i<n1;i++){
        scanf("%d",&e);
        scanf("%lf",&c1[e]);
        max1=max1>e?max1:e;
    }
    scanf("%d",&n2);
    for(int i=0;i<n2;i++){
        scanf("%d",&e);
        scanf("%lf",&c2[e]);
        max2=max2>e?max2:e;
    }
    int t1=max1,t2=max2;
    while(t1>=t2){
        double c=c1[t1]/c2[t2];
        c3[t1-t2]=c;
        for(int i=t1,j=t2;j>=0;j--,i--) c1[i]-=c2[j]*c;
        while(abs(c1[t1])<0.001) t1--;
    }
    print(c3,max1-max2);
    printf("\n");
    print(c1,t1);
    return 0;
}

来总计一下:
1)分别记录下来多项式A和多项式B的最大指数max1,max2。c3[]数组用来存储商而c1[]数组用来存储余数。
2)t1=max1,t2=max2,让c3[t1-t2]=c1[t1] / c2[t2],得到了最高次幂,和手动除法是类似的,从最高次幂向下依次开始,然后更新余数,c1[i] -= c2[i – (t1 – t2)] * c1[t1] / c2[t2],t1-t2=<i<=t1,这样完成了一次,继续乘x的某一次幂,继续更新。(一边手算一边对照会更清晰!!)
4)因为c1[]数组为double数组,所以不能写while(c1[t1]),得写while(abs(c1[t1])<0.001)。
5)因为要保留一位小数,所以要看小数点后第二位是否达到5,即a+0.05>=0.1吗?

猜你喜欢

转载自blog.csdn.net/sun9979/article/details/87868689