1002 A+B for Polynomials【PAT (Advanced Level) Practice】
原题链接:预览题目详情 - 1002 A+B for Polynomials (pintia.cn)
1.题目原文
This time, you are supposed to find A + B A+B A+B where A A A and B B B are two polynomials.
Input Specification:
Each input file contains one test case. Each case occupies 2 lines, and each line contains the information of a polynomial:
K K K N 1 N_1 N1 a N 1 a_{N_1} aN1 N 2 N_2 N2 a N 2 a_{N_2} aN2 … N K N_K NK a N K a_{N_K} aNK
where K K K is the number of nonzero terms in the polynomial, N i N_i Ni and a N i a_{N_i} aNi ( i = 1 , 2 , ⋯ , K i=1, 2, \cdots , K i=1,2,⋯,K) are the exponents and coefficients, respectively. It is given that 1 ≤ K ≤ 10 1 \le K \le 10 1≤K≤10, 0 ≤ N K < ⋯ < N 2 < N 1 ≤ 1000 0 \le N_K < \cdots < N_2 < N_1 \le 1000 0≤NK<⋯<N2<N1≤1000.
Output Specification:
For each test case you should output the sum of A A A and B B B in one line, with the same format as the input. Notice that there must be NO extra space at the end of each line. Please be accurate to 1 decimal place.
Sample Input:
2 1 2.4 0 3.2
2 2 1.5 1 0.5
Sample Output:
3 2 1.5 1 2.9 0 3.2
2. 题目翻译
这次,你应该找到 A + B A+B A+B,其中 A A A和 B B B是两个多项式。
输入规范:
每个输入文件包含一个测试用例。每个案例占据2行,每行包含多项式的信息:
K K K N 1 N_1 N1 a N 1 a_{N_1} aN1 N 2 N_2 N2 a N 2 a_{N_2} aN2 … N K N_K NK a N K a_{N_K} aNK
其中 K K K是多项式中非零项的数量, N i N_i Ni和 a N i a_{N_i} aNi( i = 1 , 2 , ⋯ , K i=1, 2, \cdots , K i=1,2,⋯,K)分别是指数和系数。已知 1 ≤ K ≤ 10 1 \le K \le 10 1≤K≤10, 0 ≤ N K < ⋯ < N 2 < N 1 ≤ 1000 0 \le N_K < \cdots < N_2 < N_1 \le 1000 0≤NK<⋯<N2<N1≤1000。
输出规范:
对于每个测试用例,您应该在一行中输出 A A A和 B B B的和,格式与输入相同。请注意,每行末尾不能有多余的空格。请精确到小数点后1位。
示例输入:
2 1 2.4 0 3.2
2 2 1.5 1 0.5
示例输出:
3 2 1.5 1 2.9 0 3.2
3.解题思路
3.1题目分析
计算两个多项式的和,在两行中分别输入两个多项式的项数,并按照指数递减输入每一项的指数和系数,多项式的和按照相同的格式输出。
3.2基本思路
实现多项式相加的算法,多项式通常有两种实现方式:数组实现和链表实现。
链表实现:多项式的每一项为链表的一个结点,结点记录系数和指数。
数组实现:数组的每一个元素表示多项式的系数,数组下标表示多项式的指数。因为指数 N ≤ 1000 N \leq 1000 N≤1000 ,所以数组大小为 1001
。
3.3详解步骤
链表实现
- 定义节点结构体和多项式类型:
- 使用结构体
Node
表示多项式的每一项,包含系数Coefficient
、指数Exponent
和指向下一项的指针Next
。 - 定义
Polynomial
为指向Node
结构体的指针,表示整个多项式。 - 使用
Attach
函数将新的节点附加到多项式的尾部。
- 使用结构体
- 比较函数:
- 定义了
COMPARE
函数,用于比较两个指数的大小,返回-1、0或1分别表示小于、等于或大于。
- 定义了
- 读取多项式:
- 使用
ReadIn
函数从输入中读取多项式。首先读取多项式的非零项数k
,然后通过循环读取每一项的指数n
和系数a
,调用Attach
函数将每一项附加到多项式的尾部。返回多项式的头指针。
- 使用
- 打印多项式:
- 使用
PrintOut
函数打印多项式。首先统计多项式的非零项数,然后输出非零项数和每一项的指数和系数。
- 使用
- 多项式相加:
- 使用
Add
函数进行多项式相加。创建一个结果多项式的头节点,然后使用循环从头节点后的第一个节点开始,依次比较两个多项式对应节点的指数:- 如果指数相等,将系数相加,结果不为零则调用
Attach
函数附加到结果多项式的尾部。 - 如果指数不相等,将较大指数对应的节点附加到结果多项式的尾部。
- 如果某个多项式的节点遍历完,将另一个多项式剩余的节点附加到结果多项式的尾部。
- 如果指数相等,将系数相加,结果不为零则调用
- 返回结果多项式的头指针。
- 使用
- 主函数:
- 读取两个多项式,并调用
Add
函数进行相加。 - 打印相加后的多项式。
- 读取两个多项式,并调用
数组实现
- 读取第一个多项式:
- 通过
scanf
读取第一个多项式的非零项数量K1
。 - 创建一个数组
poly1
,用于存储第一个多项式的系数。数组的下标表示多项式的指数,初始化为0
。 - 通过循环,读取每一项的指数
N
和系数a
,将系数存储在poly1
数组中对应的位置。
- 通过
- 读取第二个多项式:
- 通过
scanf
读取第二个多项式的非零项数量K2
。 - 创建一个数组
poly2
,用于存储第二个多项式的系数。数组的下标表示多项式的指数,初始化为0。 - 通过循环,读取每一项的指数
N
和系数a
,将系数存储在poly2
数组中对应的位置。
- 通过
- 计算结果:
- 创建一个数组
poly
,用于存储相加后的多项式的系数。数组的下标表示多项式的指数,初始化为0。 - 使用循环遍历两个多项式的系数数组,按照从高次到低次的顺序,计算相应指数的系数之和,并将结果存储在
poly
数组中。
- 创建一个数组
- 输出结果:
- 使用变量
cnt
记录相加后的多项式的非零项数量。 - 使用循环遍历
poly
数组,输出相加后的多项式的非零项数量以及每一项的指数和系数。输出格式要求小数点后保留1位。
- 使用变量
4.参考答案
链表实现
#include <stdio.h>
#include <malloc.h>
// 定义节点结构体
typedef struct Node *PtrToNode;
typedef struct Node {
double Coefficient; // 系数
int Exponent; // 指数
PtrToNode Next; // 指向下一个节点的指针
} PNode;
// 定义多项式类型
typedef PtrToNode Polynomial;
// 比较函数,用于比较两个指数的大小
int COMPARE(int a, int b) {
if (a < b)
return -1;
if (a > b)
return 1;
return 0;
}
// 将节点(包含系数和指数)附加到多项式的尾部
void Attach(double coefficient, int exponent, PtrToNode *ptr) {
PtrToNode temp;
// 分配新节点
temp = malloc(sizeof(PNode));
temp->Coefficient = coefficient;
temp->Exponent = exponent;
temp->Next = NULL;
(*ptr)->Next = temp; // 将新节点连接到尾部
*ptr = temp; // 更新尾部指针为新节点
}
// 从输入中读取多项式
Polynomial ReadIn() {
PtrToNode front, tail;
double a;
int k, n;
scanf("%d", &k);
if (!k)
return NULL; // 如果多项式的非零项数为0,则返回空指针
tail = malloc(sizeof(PNode));
front = tail;
front->Exponent = -1;
while (k--) {
scanf("%d %lf", &n, &a);
Attach(a, n, &tail);
}
return front; // 返回多项式的头指针
}
// 打印多项式
void PrintOut(Polynomial P) {
Polynomial s;
int k = 0;
s = P->Next;
while (s) {
k++;
s = s->Next;
}
printf("%d", k);
if (k) {
for (s = P->Next; s; s = s->Next)
printf(" %d %.1f", s->Exponent, s->Coefficient);
}
printf("\n");
}
// 多项式相加
Polynomial Add(Polynomial a, Polynomial b) {
PtrToNode front, tail;
double sum;
// 创建结果多项式的头节点
tail = malloc(sizeof(PNode));
front = tail;
front->Exponent = -1;
// 跳过头节点,从第一个节点开始相加
a = a->Next;
b = b->Next;
while (a && b)
switch (COMPARE(a->Exponent, b->Exponent)) {
case -1:
Attach(b->Coefficient, b->Exponent, &tail);
b = b->Next;
break;
case 0:
sum = a->Coefficient + b->Coefficient;
if (sum)
Attach(sum, a->Exponent, &tail);
a = a->Next;
b = b->Next;
break;
case 1:
Attach(a->Coefficient, a->Exponent, &tail);
a = a->Next;
break;
}
// 将剩余的节点附加到结果多项式的尾部
for (; a; a = a->Next)
Attach(a->Coefficient, a->Exponent, &tail);
for (; b; b = b->Next)
Attach(b->Coefficient, b->Exponent, &tail);
tail->Next = NULL; // 结果多项式的尾部指针置空
return front; // 返回结果多项式的头指针
}
// 主函数
int main() {
Polynomial A, B, S;
// 读取两个多项式
A = ReadIn();
B = ReadIn();
// 将两个多项式相加
S = Add(A, B);
// 打印结果多项式
PrintOut(S);
return 0;
}
数组实现
#include <stdio.h>
#define MAXN 1001
int main() {
int K1, K2, N, i;
double a;
// 读取第一个多项式
scanf("%d", &K1);
double poly1[MAXN] = {
0}; // 多项式1的系数数组,下标表示指数
for (i = 0; i < K1; ++i) {
scanf("%d %lf", &N, &a);
poly1[N] = a;
}
// 读取第二个多项式
scanf("%d", &K2);
double poly2[MAXN] = {
0}; // 多项式2的系数数组,下标表示指数
for (i = 0; i < K2; ++i) {
scanf("%d %lf", &N, &a);
poly2[N] = a;
}
//计算结果
double poly[MAXN] = {
0};
int cnt= 0;
for (i = 1000; i >= 0; --i) {
if (poly1[i] + poly2[i] != 0.0){
cnt++;
poly[i] = poly1[i] + poly2[i];
}
}
// 输出
printf("%d",cnt);
for (i = 1000; i >= 0; --i) {
if (poly[i] != 0.0)
printf(" %d %.1lf", i, poly1[i] + poly2[i]);
}
return 0;
}