1: 7-2 一元多项式的乘法与加法运算 (20 分)
来源:PTA 数据结构与算法题目集(中文)
设计函数分别求两个一元多项式的乘积与和。
输入格式:
输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。
输出格式:
输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0。
输入样例:
4 3 4 -5 2 6 1 -2 0
3 5 20 -7 4 3 1
输出样例:
15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1
5 20 -4 4 -5 2 9 1 -2 0
思路:因为指数项都是非负整数,所以我们可以把指数项当成下标,系数项当成数组的值存入数组,然后模拟一遍
#include<bits/stdc++.h>
using namespace std;
const int N=2010;
int a[N],b[N],c[N],d[N],f1[N],f2[N];
int n,m;
int main()
{
cin>>n;
for(int i=0;i<n;i++) cin>>a[i]>>b[i],f2[b[i]]+=a[i];
cin>>m;
for(int i=0;i<m;i++) cin>>c[i]>>d[i],f2[d[i]]+=c[i];
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
f1[b[i]+d[j]]+=a[i]*c[j];
}
}
int f=0;
for(int i=N;i>=0;i--)
{
if(f1[i])
{
if(f++) cout<<' ';
cout<<f1[i]<<' '<<i;
}
}
if(!f) cout<<"0 0";
cout<<endl;
int t=0;
for(int i=N;i>=0;i--)
{
if(f2[i])
{
if(t++) cout<<' ';
cout<<f2[i]<<' '<<i;
}
}
if(!t) cout<<"0 0";
return 0;
}
2: AcWing 1481. 多项式乘积
来源:PAT甲级真题1009
给定两个多项式 A 和 B,计算 A×B 的结果。
输入格式
共两行,每行包含一个多项式的信息,格式如下:
K N1 aN1 N2 aN2 … NK aNK
其中,K 表示多项式中非零项的数量,Ni 和 aNi 分别表示其中一个非零项的指数和系数。
输出格式
按照与输入相同的格式,输出 A×B 的结果。
结果中的各项的系数均保留一位小数。
数据范围
K 为整数,1≤K≤10。
Ni 为整数,0≤NK<⋯<N2<N1≤1000。
aNi 为浮点数,−100≤aNi≤100。
输入样例:
2 1 2.4 0 3.2
2 2 1.5 1 0.5
输出样例:
3 3 3.6 2 6.0 1 1.6
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 2010;
double a[N],b[N],c[N];
int main()
{
int k;
cin >> k;
for(int i=0;i<k;i++)
{
int x;
double y;
cin >> x >> y;
a[x] += y;
}
cin >> k;
for(int i=0;i<k;i++)
{
int x;
double y;
cin >> x >> y;
b[x] += y;
}
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
if(a[i] && b[j])
{
c[i + j] += a[i] * b[j];
}
}
}
int cnt = 0;
for(int i=0;i<N;i++)
if(c[i]) cnt ++;
cout << cnt;
for(int i=N;i>=0;i--)
if(c[i]) printf(" %d %.1f",i,c[i]);
return 0;
}
3: L2-018 多项式A除以B (25 分)
来源:PTA 团体程序设计天梯赛-练习集
这仍然是一道关于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>
using namespace std;
const int N=20010;//注意空间开小了会有个点过不去
double a[N],b[N],c[N];
void rd(double f[],int idx)
{
int res=0;
for(int i=0;i<=idx;i++)
if(abs(f[i])>=0.05) res++;//记录多项式的项数
cout<<res;
if(res==0) cout<<" 0 0.0";//零多项式
for(int i=idx;i>=0;i--)
if(abs(f[i])>=0.05)
printf(" %d %.1lf",i,f[i]);//按指数递减输出
}
int main()
{
int n,m,x,idx1=-1e9,idx2=-1e9;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>x;
cin>>a[x];//把系数和指数关联在一起
if(idx1<x) idx1=x;//找到被除数的最大指数
}
cin>>m;
for(int i=0;i<m;i++)
{
cin>>x;
cin>>b[x];
if(idx2<x) idx2=x;
}
int idx3=idx1-idx2;//商的最大指数
while(idx1-idx2>=0)
{
double p=a[idx1]/b[idx2];//商的系数
c[idx1-idx2]=p;//商的指数
for(int i=idx1,j=idx2;i>=0&&j>=0;i--,j--) a[i]-=p*b[j];//余数
while(!a[idx1]) idx1--;//零次项直接跳过
}
rd(c,idx3);
cout<<endl;
rd(a,idx1);
return 0;
}