甲级PAT 1002 A+B for Polynomials(附解坑说明)

题目:

1002 A+B for Polynomials (25)(25 分)

This time, you are supposed to find A+B where A and B are two polynomials.

Input

Each input file contains one test case. Each case occupies 2 lines, and each line contains the information of a polynomial: K N1 a~N1~ N2 a~N2~ … NK a~NK~, where K is the number of nonzero terms in the polynomial, Ni and a~Ni~ (i=1, 2, …, K) are the exponents and coefficients, respectively. It is given that 1 <= K <= 10,0 <= NK < … < N2 < N1 <=1000.

Output

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分别存储输入的指数和系数。然后对两个数组按指数从大到小排序后,利用归并排序合并成一个数组。这个数组也是按照从大到小排序,因此按格式输出即可。

坑1:输出格式——输出格式最后一个不能输出空格,输出精度要精确到0.1

#include<iostream>
#include<algorithm>
#include<iomanip>
using namespace std;
#define maxsize 11

typedef struct {
	int e; //指数 
	float c;  //系数 
}pol;

bool comp(pol a,pol b){
	return a.e > b.e;
}

int main(){
	int anum,bnum,i,j,k;
	pol a[maxsize],b[maxsize],c[maxsize*2];
	cin>>anum;
	for(i=1;i<=anum;i++){
		cin>>a[i].e;
		cin>>a[i].c;
	}
	cin>>bnum;
	for(i=1;i<=bnum;i++){
		cin>>b[i].e;
		cin>>b[i].c;
	}
	sort(a+1,a+anum+1,comp);
	sort(b+1,b+bnum+1,comp);
	i=1;j=1;k=1;
	while(i<=anum&&j<=bnum){
		if(a[i].e>b[j].e){
			c[k].c = a[i].c;
			c[k].e = a[i].e;
			k++;
			i++;
		}else if(a[i].e==b[j].e){
			c[k].c = a[i].c+b[j].c;
			c[k].e = a[i].e;
			k++;
			i++;
			j++;			
		}else{
			c[k].c = b[j].c;
			c[k].e = b[j].e;
			k++;
			j++;
		}
	}
	while(i<=anum){
		c[k].c = a[i].c;
		c[k].e = a[i].e;
		k++;
		i++;
	}
	
	while(j<=bnum){
		c[k].c = b[j].c;
		c[k].e = b[j].e;
		k++;
		j++;		
	}
	
	cout<<k-1<<" ";
	for(i=1;i<k;i++){
		if(i!=k-1){
			cout<<c[i].e<<" "<<fixed<<setprecision(1)<<c[i].c<<" "; 
		}else{
			cout<<c[i].e<<" "<<fixed<<setprecision(1)<<c[i].c;
		}	
	}
		
	
	return 0; 
}

提交的时候发现只有三个通过。

坑2:没有考虑到一行能输入相同的指数。按照上述思路对于输入相同的指数其系数不能合并,因此最后输出的时候会输出多次相同指数的。

坑3:没有考虑到系数和为0的情况。系数和不仅大于0还可以小于0。系数和为0这种情况应该是不输出的。之前判断系数>0保存该指数的下标。然后总是有一个不通过。。这个问题找了好久。。。有的系数和会为负数。改为系数和!=0的时候,就能通过。

修改后的代码(重新换了一种思路,利用下标存储指数,利用数组的值存储指数对应的系数):

#include<iostream>
#include<iomanip>
#include<cstring>
using namespace std;
#define maxsize 1002

int main(){
	int anum,bnum,i,ei;
	float c[maxsize],ci;
	int e[20];
	memset(c,0,sizeof(c));
	
	cin>>anum;
	for(i=1;i<=anum;i++){
		cin>>ei>>ci;
		c[ei]+=ci;
	}
	cin>>bnum;
	for(i=1;i<=bnum;i++){
		cin>>ei>>ci;
		c[ei]+=ci;
	}
	int num=0;
	for(i=1001;i>=0;i--){
		if(c[i]!=0){
			e[num++]=i;
		}
	}
	
	if(num==0){
		cout<<num;
	}else{
		cout<<num<<" ";
	}
	
	for(i=0;i<=num-1;i++){
		if(i!=num-1){
			cout<<e[i]<<" "<<fixed<<setprecision(1)<<c[e[i]]<<" ";
		}else{
			cout<<e[i]<<" "<<fixed<<setprecision(1)<<c[e[i]];
		}
	}
	return 0; 
}

实用的c++算法小笔记:

1.sort()排序方法,可以对结构体进行排序

2.利用iomanip库中的fixed<<setprecision(1)可以设置小数点后精度

3.cstring库中的memset()可以对数组初始化0

   int arr[1000]

    memset(arr,0,sizeof(arr))

点赞