L2-018 polynomial A divided by B (25 points)

Posted by patmcv on Sat, 29 Jan 2022 07:35:06 +0100

two

L2-018 polynomial A divided by B (25 points)

This is still A question about A/B, but both A and B are replaced by polynomials. You need to calculate the quotient Q and remainder r of the division of two polynomials, where the order of R must be less than the order of B.

Input format:

The input is divided into two lines. Each line gives A non-zero polynomial, giving A first and then B. The format of each line is as follows:

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

Where N is the number of non-zero terms of the polynomial, e[i] is the exponent of the ith non-zero term, and c[i] is the coefficient of the ith non-zero term. Each item is given in the order of decreasing exponents to ensure that all exponents are different non negative integers, all coefficients are non-zero integers, and all integers are within the integer range.

Output format:

The quotient and remainder are output successively in two lines. The output format is the same as the input format, and the output coefficient retains 1 decimal place. The numbers in the same line shall be separated by one space, and there shall be no extra space at the beginning and end of the line. Note: Zero polynomial is a special polynomial, and the corresponding output is 0.0. However, non-zero polynomials cannot output terms with zero coefficients (including 0.0 after rounding). In the example, the copolynomial actually has a constant term of - 1 / 27, but it is not output because it is rounded to 0.0.

Input sample:

4 4 1 2 -3 1 -1 0 -1
3 2 3 1 -2 0 1

Output example:

3 2 0.3 1 0.2 0 -1.0
1 1 -3.1

Problem solving ideas

 

Step 1:

1. There are coefficients and indexes, so map is used to store data types

map<int,double>a;  //remainder
map<int,double>b;  //Divisor
map<int,double>c;   //merchant

2. Initialize polynomials

① Initialization of a

int lena;   //Number of items in a
cin>>lena;
for(int i=0;i<lena;i++)
{
   int e;   //index
   double c;  //coefficient
   cin>>e>>c;
   maxe_a=max(maxe_a,e);    //Find the highest index of a
   a[e]=a[e]+c;
}

② Initialization of b

Note: b also needs to find a minimum number of times

int lenb;   //Number of items in b
cin>>lenb;
for(int i=0;i<lenb;i++)
{
   int e;   //index
   double c;  //coefficient
   cin>>e>>c;
   mine_b=min(mine_b,b);    //Find the lowest sub index of b
   maxe_b=max(maxe_b,e);    //Find the highest index of a
   b[e]=b[e]+c;   
}

Step 2: division operation

1. Calculation times:

(maxe_a-maxe_b)+1, i.e. for (int i = maxe_a; I > = maxe_b; I --)

That is, perform several division operations

2. Supplier:

The coefficient of current a is: the highest power coefficient of current a / the highest power coefficient of b

The index of current a is: the highest power of current a - the highest power of current b

Remainder item c: the item that has not been truncated to 0

One of the terms of quotient is the highest power coefficient of current a divided by the highest power coefficient of b

The same is true of the index

Why add a current?

----->Each time the highest item of a is eliminated by (the highest item of b * one item of the corresponding quotient) until a finally becomes the remainder of the requirement

------>The remainder term is the term in which the coefficient is not reduced to 0 after the difference of each term of a (each term of b * the quotient of the corresponding term)

for(int i=maxe_a;i>=maxe_b;i--)        //Number of division operations
{
  if(b[maxe_b]!=0)       //When the coefficient of b is not 0
  {
     div=1.0*a[i]/b[maxe_b];        //Coefficient of c
     sub=i-maxe_b;         //Index of c
     c[sub]=div;          //remainder
     maxe_c=max(maxe_c,sub);      //The largest exponent in the remainder
     for(int j=i;j>=mine_b;j--)    //Update vendors
     {
       if(j-sub>=0)         //When the index is not 0
          a[j]=a[j]-b[j-sub]*c[sub];      //merchant
     }
  }
}

3. Rounding operation

for(int i=maxe_c;i>=0;i--)
{
  c[i]=(double)((int)(c[i]*10+(c[i]<0?-0.5:0.5)))/10;
  if(c[i])
  cnt++;
}

Original code of the whole program

#include<iostream>
using namespace std;
#include<map>
#include<algorithm>
#include<cmath>
int main()
{
    map<int,double>a;
    map<int,double>b;
    map<int,double>c;
    int lena,lenb;
    int maxe_a=0,maxe_b=0,maxe_c=0,mine_b=10000;
    double div;
    int sub;
    cin>>lena;
    for(int i=0;i<lena;i++)
    {
        int e;
        double c;
        cin>>e>>c;
        maxe_a=max(maxe_a,e);
        a[e]=a[e]+c;
    }
    cin>>lenb;
    for(int i=0;i<lenb;i++)
    {
        int e;
        double c;
        cin>>e>>c;
        mine_b=min(mine_b,e);
        maxe_b=max(maxe_b,e);
        b[e]=b[e]+c;
    }
    for(int i=maxe_a;i>=maxe_b;i--)
    {
        if(b[maxe_b]!=0)
        {
            div=1.0*a[i]/b[maxe_b];
            sub=i-maxe_b;
            c[sub]=div;
            maxe_c=max(maxe_c,sub);
            for(int j=i;j>=mine_b;j--)
            {
                if(j-sub>=0)
                    a[j]=a[j]-b[j-sub]*c[sub];
            }
        }
    }

    int cnt=0;
    for(int i=maxe_c;i>=0;i--)
    {
        c[i]=(double)((int)(c[i]*10+(c[i]<0?-0.5:0.5)))/10;
        if(c[i])
            cnt++;
    }
    if(cnt==0)
        printf("0 0 0.0\n");
    else
    {
        cout<<cnt;
        for(int i=maxe_c;i>=0;i--)
        {
            if(c[i])
                printf(" %d %.1lf",i,c[i]);
        }
        printf("\n");
    }

    cnt=0;
    for(int i=maxe_a;i>=0;i--)
    {
        a[i]=(double)((int)(a[i]*10+(a[i]<0?-0.5:0.5)))/10;
        if(a[i])
            cnt++;
    }
    if(cnt==0)
        printf("0 0 0.0\n");
    else
    {
        cout<<cnt;
        for(int i=maxe_a;i>=0;i--)
        {
            if(a[i])
                printf(" %d %.1lf",i,a[i]);
        }
        printf("\n");
    }
    return 0;
}

summary

1. Distinguish quotient and remainder. c is quotient and a is remainder

2. For the first large cycle, determine the coefficient and index of one quotient at a time

3. The second small cycle updates the remainder a, a[j]=a[j]-b[j-sub]*c[sub]\

4. Rounding operation:

   a[i]=(double)((int)(a[i]*10+(a[i]<0?-0.5:0.5)))/10;

Topics: C++ data structure map