这仍然是一道关于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<bits/stdc++.h>
using namespace std;
struct node
{
int e;
double c;
}b[100005];//用来存除式
map<int,double>mp1;//用来存被除式 其实也算是最后的余数
map<int,double>mp2;//用来存商
int main()
{
int n, m ;
scanf("%d",&n);
int maxn = 0;
//存被除式 其实也就是最后的余数
for(int i = 0; i < n ; i ++)
{
int e;
double c;
scanf("%d %lf",&e,&c);
mp1[e] = c;
if(i == 0)
maxn = e;//表示这是被除式中最大的那个
}
//存除式
scanf("%d",&m);
for(int i = 1; i <= m ; i ++)
scanf("%d %lf",&b[i].e,&b[i].c);
//开始多项式相除
for(int i = maxn; i >= b[1].e ; i --)//多项式相除就是分子的第一个去除以分母的第一个 然后再用得到的数去乘以除式就ok
{
int t = i - b[1].e;//表示说它的项是多少
double gg = mp1[i] / b[1].c;//表示说系数是多少
mp2[t] = gg;//这个是商 存商用的
//之后开始就是更新被除式了
for(int j = 1 ; j <= m; j ++)
mp1[b[j].e + t] = mp1[b[j].e + t] - gg * b[j].c; //更新被除式 用自己减去相乘的那些东西
}
//开始输出
int ans1 = 0 ,ans2 = 0;
for(int i = 0 ; i <= maxn; i++)
{
if(fabs(mp1[i]) < 0.05) mp1[i] = 0;
if(fabs(mp2[i]) < 0.05) mp2[i] = 0; //记得加fabs
if(mp1[i] != 0) ans1++;
if(mp2[i] != 0) ans2++;
}
//输出商
printf("%d",ans2);
for(int i = maxn; i >= 0; i--)
{
if(mp2[i] != 0)
printf(" %d %.1lf",i,mp2[i]);
}
if(ans2 == 0)
printf(" 0 0.0");
printf("\n");
//输出余数
printf("%d",ans1);
for(int i = maxn; i >= 0; i--)
{
if(mp1[i] != 0)
printf(" %d %.1lf",i,mp1[i]);
}
if(ans1 == 0)
printf(" 0 0.0");
printf("\n");
return 0;
}