题意
- 模拟多项式相乘。
注意
- 不会有零项。
- 开一个
2*MAX-1
的数组存放结果。 memset
过检测需要加头文件cstring
scanf
读取double
类型需要%lf
代码
#include <iostream>
#include <cstring>
using namespace std;
const int MAX = 1001;
double n1[MAX];
double n2[MAX];
double p[2*MAX-1];
bool b1[MAX];
bool b2[MAX];
int k1, k2;
void product()
{
for (int i = 0; i < MAX; i++)
{
if (!b1[i])
continue;
for (int j = 0; j < MAX; j++)
{
if (!b2[j])
continue;
p[i + j] += n1[i] * n2[j];
}
}
int c = 0;
for (int i = 0; i < 2 * MAX - 1; i++)
if (p[i] != 0)
c++;
printf("%d", c);
for (int i = 2 * MAX - 2; i >= 0; i--)
if (p[i] != 0)
printf(" %d %.1f", i, p[i]);
}
int main()
{
fill(b1, b1 + MAX, false);
fill(b2, b2 + MAX, false); //每个元素赋值 区间[a,b)
memset(p, 0, sizeof p); //每个字节赋值 头文件 cstring
int n;
scanf_s("%d", &k1);
for (int i = 0; i < k1; i++)
{
scanf_s("%d", &n);
scanf_s("%lf", &n1[n]); //scanf读取double要用 "%lf" , printf不区分
b1[n] = true;
}
scanf_s("%d", &k2);
for (int i = 0; i < k2; i++)
{
scanf_s("%d", &n);
scanf_s("%lf", &n2[n]);
b2[n] = true;
}
product();
return 0;
}
再来一个。。
(19年5月6日)不同于多项式相加,相乘出来了k1*k2
个项,这些项都不会为0
,但是要合并同类项,合并的过程中就有可能出来0
了!(比如(x^4 + x^2)(x^4 - x^2)
)
上面的代码是直接以指数的范围为数组大小来存系数,然后在整个指数空间里相乘,这样以+=
自动完成了合并同类项的过程。(然而没必要以整个范围来循环。。而且当时还用memset
来初始化double
了。。)
下面是只对这些项相乘,然后以指数排序,然后再合并同类项,要判断合并后为0
的情况。(这个合并的过程比较巧妙)
#include <iostream>
#include <cstring> //要不用不了memset()
#include <algorithm>
using namespace std;
const int MAX = 11;
int k1, k2;
struct ss
{
int e;
double co;
};
ss s1[MAX], s2[MAX], s3[MAX*MAX];
bool cmp(const ss s1, const ss s2)
{
return s1.e > s2.e;
}
void product()
{
int x = 0;
for (int i = 0; i < k1; i++)
{
for (int j = 0; j < k2; j++)
{
s3[x].co = s1[i].co * s2[j].co;
s3[x++].e = s1[i].e + s2[j].e;
}
}
sort(s3, s3 + x, cmp);
//1
int x0 = 0;
for (int i = 0; i < x;)
{
for (int j = i + 1;;)
{
if (j < x && s3[i].e == s3[j].e)
{
s3[i].co += s3[j].co;
j++;
}
else // 完成收尾工作,每一个不同的指数项都必将运行到这里
{
if (s3[i].co != 0.0) // 先乘后加的过程,乘的时候不会有,加的时候可能会有系数为0的情况
{ // 19.3.6
s3[x0].e = s3[i].e;
s3[x0++].co = s3[i].co; // 合并后的可以放在同一个数组上,因为 x0<=i
}
i = j;
break;
}
}
}
printf("%d", x0);
for (int i = 0; i < x0; i++)
printf(" %d %.1f", s3[i].e, s3[i].co);
//1
//2 // 调试时写的,和1作用等价
/*double s[2001];
for (int i = 0; i < 2001; i++)
s[i] = 0.0;
for (int i = 0; i < x; i++)
s[s3[i].e] += s3[i].co;
int cnt = 0;
for (int i = 0; i < 2001; i++)
if (s[i] != 0.0) cnt++; // 判断double类型是否为0不能用!(x)
printf("%d", cnt);
for (int i = 2000; i >= 0; i--)
if (s[i] != 0.0) printf(" %d %.1f", i, s[i]);*/
//2
}
int main()
{
int n;
scanf_s("%d", &k1);
for (int i = 0; i < k1; i++)
{
scanf_s("%d", &s1[i].e);
scanf_s("%lf", &s1[i].co); //scanf读取double要用 "%lf" , printf不区分
}
scanf_s("%d", &k2);
for (int i = 0; i < k2; i++)
{
scanf_s("%d", &s2[i].e);
scanf_s("%lf", &s2[i].co);
}
product();
return 0;
}