传送门
// 感觉这道题还是挺坑的, 做法当然是模拟来做. 就是可能有一个点大家没理解清楚, 那就是说的系数为0的项不进行输出, 如果最后没有项, 那么在输出零多项式(即 0, 0), 剩下的做法就是模拟题意来做多项式加法和乘法就是了.
AC Code
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pii pair<int,int>
#define mk make_pair
const int maxn = 2000;
pii a[maxn], b[maxn];
pii ans1[maxn];
struct node {
int x, y;
bool operator < (const node & a) const {
return y > a.y;
}
}ans2[maxn];
int add(int n, int m) { // 注意系数为零的不要.
int k = 0 , c1 = 1, c2 = 1;
while(c1 <= n && c2 <= m) {
if (a[c1].se == b[c2].se) {
if (a[c1].fi + b[c2].fi) ans1[++k] = mk(a[c1].fi + b[c2].fi, a[c1].se);
c1++; c2++;
}
else if (a[c1].se > b[c2].se) {
ans1[++k] = mk(a[c1].fi, a[c1].se);
c1++;
}
else {
ans1[++k] = mk(b[c2].fi, b[c2].se);
c2++;
}
}
if (c1 <= n) for (int i = c1 ; i <= n ; i ++) ans1[++k] = mk(a[c1].fi, a[c1].se);
else for (int i = c2 ; i <= m ; i ++) ans1[++k] = mk(b[c2].fi, b[c2].se);
return k;
}
int mutiply(int n, int m) {
int k = 0;
for (int i = 1 ; i <= n ; i ++) {
for (int j = 1 ; j <= m ; j ++) {
if (!a[i].fi || !b[j].fi) ans2[++k] = node{0, 0};
else ans2[++k] = node{a[i].fi*b[j].fi, a[i].se + b[j].se};
}
}
sort(ans2 + 1 , ans2 + 1 + k);
int k2 = 0, cnt;
for (int i = 1 ; i <= k ; i += cnt) { // 合并同类项
int sum = ans2[i].x, pp = ans2[i].y; cnt = 1;
for (int j = i + 1 ; j <= k ; j ++) {
if (ans2[j].y != pp) break;
sum += ans2[j].x; cnt++;
}
if (sum) ans2[++k2] = node{sum, pp};
}
sort(ans2 + 1 , ans2 + 1 + k2);
return k2;
}
int main() {
freopen("in.txt","r",stdin);
int n, m;
scanf("%d", &n);
for (int i = 1 ; i <= n ; i ++) {
int u, v;
scanf("%d%d", &u, &v);
a[i] = mk(u, v);
}
scanf("%d", &m);
for (int i = 1 ; i <= m ; i ++) {
int u, v;
scanf("%d%d", &u, &v);
b[i] = mk(u, v);
}
int cnt1 = add(n, m);
int cnt2 = mutiply(n, m);
if (!cnt2) printf("0 0\n");
for (int i = 1 ; i <= cnt2 ; i ++) {
printf("%d %d%c", ans2[i].x, ans2[i].y , i == cnt2 ?'\n':' ');
}
if (!cnt1) printf("0 0\n");
for (int i = 1 ; i <= cnt1 ; i ++) {
printf("%d %d%c", ans1[i].fi, ans1[i].se , i == cnt1 ?'\n':' ');
}
}