问题描述:设计函数分别求两个一元多项式的乘积与和。
代码长度限制:16 KB
时间限制:200 ms
内存限制:64 MB
输入格式:
输入分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
解题思路:
这个题我用的c++ STL的map容器解的。
因为多项式的表达方式和map的特点有很多相似的地方:
先讲乘法优点:
- 多项式中,不会有两项指数相同的项,如果有的话会合并,也是一项。恰好map容器的关键字不能重复。所以我们把每一项的指数定为关键字,每一项的系数定为值,这样map的每项就是多项式的每一项。
- 定义三个map对象,mp1,mp2和result,多项式相乘,就是mp1的每一项和mp2的每一项乘积,两项乘积即指数相加,系数相乘。如果result结果中没有关键字是该两项乘积指数的项,那加上这一项,该项的值就是系数乘积。
- 多项式相乘,可能乘出来的结果会有合并的情况,比如a* x¹ * b *x³和c * x² * d * x²,这两个相乘的结果可以合并,那无非就是在mp[4]上面添加即可。
- 因为map用红黑树实现,在给我们把项按关键字(指数)的同时效率也比较高。既然他给我们排好序了,就便于我们打印了。
加法优点:
先把结果定为第一个多项式,再在第一个多项式中加上第二个。把第二个多项式按项数遍历。如果第二项的指数在第一项有,那就直接把系数加上。如果没有,那就在result中再开一项,开到哪个位置都行,因为map容器自动排序。
附:为啥可以对应项相加?因为map自动排序…
代码实现:
#include<iostream>
#include<map>
using namespace std;
int main( )
{
map<int, int> mp1, mp2 , mr, ar;//multiple result 和addition result
//第一个int是指数,关键字,第二个int是系数,值
map<int, int>::iterator it1, it2;
int n, m;
int temp1, temp2;
//the input of the first map's information
cin >> n;
for(int i = 0; i < n; ++ i)
{
cin >> temp1 >> temp2;//先输入系数,后输入指数
mp1[temp2] = temp1;
}
//the input of the second map's information
cin >> m;
for(int i = 0; i < m; ++ i)
{
cin >> temp1 >> temp2;
mp2[temp2] = temp1;
}
//乘法计算,变历让map1和map2中的每一项相乘
for(it1 = mp1.begin(); it1 != mp1.end(); it1 ++)
{
for(it2 = mp2.begin(); it2 != mp2.end(); it2 ++)
{
int x = (it1->first) + (it2->first);//两项相乘指数相加
if(mr.find(x) == mr.end())//结果中没有这个指数时先置系数为0
mr[x] = 0;
mr[x] += (it1->second) * (it2->second);//加上新产生的结果
if(mr[x] == 0)//如果两个结果加起来系数是0了,删除这一项
mr.erase(x);
}
}
//多项式加法
ar = mp1;//先把mp1赋给结果
for(it2 = mp2.begin(); it2 != mp2.end(); it2 ++)
{
if(ar.find(it2->first) == ar.end())//原来没这个指数项时置0
ar[it2->first] = 0;
ar[it2->first] += it2->second;//加上新结果
if(ar[it2->first] == 0)//系数为0时清除这一项
ar.erase(it2->first);
}
//output multiple result
//如果有个多项式为0,乘法结果必为0,或者是乘法算完后结果为0
if( m == 0 || n == 0 || mr.size() == 0)
cout << "0 0"<<endl;
else{
it2 = mr.end();//先打印指数大的
it2 --;
for(it1 = it2; it1 != mr.begin(); it1 --)
cout << it1->second << ' ' << it1->first << ' ';
cout << it1->second << ' ' << it1->first <<endl;
}
//output add result
if(ar.size() == 0)
{
cout << "0 0"<<endl;
}
else{
it2 = ar.end();
it2 --;
for(it1 = it2; it1 != ar.begin(); it1 --)
cout << it1->second << ' ' << it1->first << ' ';
cout << it1->second << ' ' << it1->first;
}
return 0;
}