PTA | 1002 A+B for Polynomials
作者 CHEN, Yue
单位 浙江大学
This time, you are supposed to find A+B where A and 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 N1 aN1 N2 aN2 ... NK aNK
where K is the number of nonzero terms in the polynomial, Ni and aNi (i=1,2,⋯,K) are the exponents and coefficients, respectively. It is given that 1≤K≤10,0≤NK<⋯<N2<N1≤1000.
Output Specification:
For each test case you should output the sum of A and 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
万事开头难,先读题!
本题的大致意思是:
这次,你应该找到A+B,其中A和B是两个多项式。
输入规格:
每个输入文件包含一个测试用例。每个测试用例占用2行,每行包含一个多项式的信息:
K N1 aN1 N2 aN2 ... NK aNK
其中K是多项式中非零项的数量,Ni 和 aNi (i=1,2,⋯,K)分别是指数和系数。给定1≤K≤10,0≤NK<⋯<N2<N1≤1000。
输出规格:
对于每个测试用例,你应该在一行中输出A和B的和,格式与输入相同。请注意,每行的末尾必须没有多余的空格。请精确到小数点后1位。
读完题目之后,我们可以提取到以下关键信息:
- 1, 本题的目的是多项式相加求和,即同次数项系数相加求和
- 2,单次输入用例包含两行,每行包括:非零项项数,各项的指数和系数,并且包含零次项
- 3, 最多十项,最高项次数不会超过1000
- 4, 输出格式和输入相同,没有多余空格,精确到一位小数
提取完信息之后,我们就可以在开始手搓代码了!
首先,根据题目要求:
最高次项不会超过1000次,即说明多项式最多项数将不会超过1001项
据此我们可以创建一个 大小为1001,类型为double 的系数数组,用于存储系数,此后则根据输入,设立变量k,使用循环持续为系数数组进行输入,同时对次数相同项进行系数合并(xishu[n] += 输入的系数),注意此处为:+=,与原有的数值相加,并不是覆盖赋值!
C++代码如下:
double xishu[1001] = {0};
int temp = 2;
while(temp --){
int k = 0;
cin >> k;
while(k--){
int n;
double d;
cin >> n >> d;
xishu[n] += d;
}
}
python代码如下:
值得注意的是,为了后续操作的方便,python中多定义了一个指数数组,用于记录指数。定义max_变量用于记录最大指数。
zhishu = [0 for i in range(1001)]
xishu = zhishu.copy()
max_ = -1
for i in range(2):
temp = [eval(j) for j in input().split()][1:]
for j in range(0, len(temp), 2):
zhishu[-(temp[j]+1)] = temp[j]
max_ = max(zhishu[-(temp[j]+1)], max_ )
xishu[-(temp[j]+1)] += temp[j+1]
以上则是输入部分;
其次,我们根据输入对数据进行操作。
第一步则是统计非零项的个数,最简单的方法就是将xishu数组进行遍历,只要其中元素不为零,则纳入计算,其中C++可以考虑使用map容器,定义为map<int, double>,根据map容器的特性,全零项将不计入考虑,统计非零项数时直接获取map容器的size,可以稍微简化一点代码;python中,由于遍历较慢,可以用上之前定义max_,使用for循环从后向前遍历系数数组,最多只需要遍历到max_ + 1项即可全部遍历完,当然由于range函数左闭右开的性质,此处遍历端点应该为-(max_ + 2)以确保max_ + 1项能取到。当然C++部分代码也可以采取这种策略。
第二步则是格式化输出的部分,这部分较为简单,由于涉及到保留小数位数,建议使用原始的输入输出格式即 %m.nd/f,其中m是整体输出的长度,n是保留小数位数。
其中,C++部分代码如下:
int count = 0;
for(int i = 0; i <= 1001; i++){
if(xishu[i] != 0){
count ++; // 非零项项数统计
}
}
cout << count;
for(int i = 1000; i >=0; i --){
if(xishu[i] != 0){
printf(" %d %.1f", i, xishu[i]);
}
}
python部分如下:
count = 0
str_ = ''
for i in range(-1, -max_-2, -1):
if xishu[i] != 0:
count += 1
str_ = " %d %.1f" % (zhishu[i], xishu[i]) + str_
str_ = str(count) + str_
print(str_)
这两者中,格式化输出的策略不同,C++使用cout函数先输出了count,后面的部分则采用printf进行输出,python则是先定义了str_为空,对str_进行左拼接,防止右边多出空格。
完整的代码如下:
C++部分:
#include<bits/stdc++.h>
using namespace std;
int main(){
double xishu[1001] = {0};
int temp = 2;
while(temp --){
int k = 0;
cin >> k;
while(k--){
int n;
double d;
cin >> n >> d;
xishu[n] += d;
}
}
int count = 0;
for(int i = 0; i <= 1001; i++){
if(xishu[i] != 0){
count ++; // 非零项项数统计
}
}
cout << count;
for(int i = 1000; i >=0; i --){
if(xishu[i] != 0){
printf(" %d %.1f", i, xishu[i]);
}
}
}
python部分:
zhishu = [0 for i in range(1001)]
xishu = zhishu.copy()
max_ = -1
for i in range(2):
temp = [eval(j) for j in input().split()][1:]
for j in range(0, len(temp), 2):
zhishu[-(temp[j]+1)] = temp[j]
max_ = max(zhishu[-(temp[j]+1)], max_ )
xishu[-(temp[j]+1)] += temp[j+1]
count = 0
str_ = ''
for i in range(-1, -max_-2, -1):
if xishu[i] != 0:
count += 1
str_ = " %d %.1f" % (zhishu[i], xishu[i]) + str_
str_ = str(count) + str_
print(str_)
最后附上AK截图:
C++部分:
python部分:
写在后面:
由于本题不涉及算法和数据结构方面的应用,总体来说难度不大,考察重点在于对细节的把控和格式化输出的应用,读题时应小心谨慎。