(PTA记录)1002 A+B for Polynomials (25分)

(PTA记录)1002 A+B for Polynomials (25分)

题目内容:
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 N​1​​ a​N​1​​​​ N​2​​ a​N​2​​​​ … N​K​​ a​N​K​​​​
where K is the number of nonzero terms in the polynomial, N​i​​ and a​N​i​​​​ (i=1,2,⋯,K) are the exponents and coefficients, respectively. It is given that 1≤K≤10,0≤N​K​​<⋯<N​2​​<N​1​​≤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

可能需要到的单词:
polynomials: 多项式的;
exponent: 指数,幂;
coefficient: 系数;
respectively: 分别得,各自得;
format: 格式;
accurate: 准确地;
decimal: 十进制地;

我的代码(由于本人目前水平不高,所以代码很小白,只在关键地方有注释,主要是记录期间遇到的问题):
通过率:100%;

#include <iostream>
#include <string> 
#include <iomanip>
int main(){
    int k1,k2,ex;
    double co;
    cin >> k1;
    int e1[k1];
    double c1[k1];
    for(int i = 0;i < k1;i++){
        cin >> ex;
        e1[i] = ex;
        cin >> co;
        c1[i] = co;
    }
    cin >> k2;
    int e2[k2];
    double c2[k2];
    for(int i = 0;i < k2;i++){
        cin >> ex;
        e2[i] = ex;
        cin >> co;
        c2[i] = co;
    }
    int count = k1 + k2,min = -1,v1 = 0,v2 = 0;
    int out1[count];
    double out2[count];
    for(int i = k1 - 1;i >= 0;i--){
        for(int j = k2 - 1;j >= 0;j--){
            if(e1[i] != e2[j]){        
            /*这里是这样的,首先是让数组 e1和 e2倒序从他们的最小值开始比较,
            先比较两个数组当前序列哪个小,再用小的和目前存在 out1里面的最小值比,
            如果比 out1里面的最小值(即 min)小,添加到 out1,并更新 min的值
            这个可以自己试一哈,我在草稿纸试了很多例子发现可行,就是倒序中找最小的放入*/
                if(e1[i] >= e2[j] && e2[j] > min){
                    out1[v1++] = e2[j];
                    out2[v2++] = c2[j];
                    min = e2[j];
                }else if(e2[j] > e1[i] && e1[i] > min){
                    out1[v1++] = e1[i];
                    out2[v2++] = c1[i];
                    min = e1[i];
                }
            }else{        			//当幂相等时,上面的填入最小值仍生效
                count--;			//原来有的多项式的个数就要减去1
                double s = c1[i] + c2[j];	//测试点0,1,2 错写int型
                if(s != 0){			//测试点3,4,5,判断系数相加是否为0
                   out1[v1++] = e1[i];
                   out2[v2++] = s; 
                }else{
                    count--;			//这里注意,如果系数为空了,没有这一项,count需要再减一次1
                }
                min = e1[i];
            }
        }
    }
    if(e1[0] > e2[0]){				//这个if-else语句就是当k1,k2个数不相等会有一个多出来,找到所有比mid大的,依次加入out就好了
        for(int i = 0;i < k1;i++){
            if(e1[i] > min){
                out1[v1++] = e1[i];
                out2[v2++] = c1[i];
            }
        }
    }else{
    	 for(int i = 0;i < k2;i++){
            if(e2[i] > min){
                out1[v1++] = e2[i];
                out2[v2++] = c2[i];
            }
        }
    }
    if(count != 0){
        cout<<count<<" ";
        for(int i = v1 - 1;i >= 0;i--){		//out中的序数是倒着的,所以需要反过来
            if(i == 0){				//以下两种输出方式均可。
                //printf("%d %.1f",out1[i],out2[i]);
                cout<<out1[i]<<" "<<setiosflags(ios::fixed)<<setprecision(1)<<out2[i];
            }else{
                //printf("%d %.1f ",out1[i],out2[i]);
                cout<<out1[i]<<" "<<setiosflags(ios::fixed)<<setprecision(1)<<out2[i]<<" ";
            }
        }
     }else{
        cout<<"0";				//测试点6,没有任何项,输出0
     }
    return 0;
}

代码其实挺简单易懂的,但说实话我也看不下去,时间和空间复杂度太大了。。。好歹通过了(嘤嘤嘤)。
遇到问题及解决流程:
1.测试点0.1.2:
(注意double型和int型的使用和结果的输出)
首先我在解决了遇到的编译问题(。。。)后,只通过了一个测试点,就目前来看,那个测试点的记录中系数应该都是int型,所以通过了。然后我通过线上的c++编译器运行了一下我的代码,发现结果本应是2.9的地方却是2.0,于是我找到了我写的时候犯得一个小错误,在新建一个s使s等于幂相等的系数和的时候我竟然新建了一个int型。。。
2.测试点3.4.5:
(注意相等幂的两项系数和正好为0)
网上查找资料有提醒说会有幂相等的两个系数和为0的情况,此时需要删除该项,于是我加了和为0的判断,我以为解决了,其实并没有,因为疏忽了这个项删除后前面的计数(我这里是count)也应该减1。
3.测试点6:
(注意没有输入任何项)
在解决了3.4.5而6没通过时我本能的想到了可能是输入为空,于是我试了输入为空时输出为空和输出为“0,0”(我吐了),结果都不行,于是网上找了一个全通过的放上去试了一下,发现输出结果是“0”。所以后面加了个判断输出0。

以上便是我这道题在编写时遇到的问题,用以记录。

以下是网上找到的使用映射法的较优解:

#include <iostream>  
#include <string> 
#include <iomanip>
#include <stdio.h>
#include <string.h>
using namespace std;
int main(){  
    float hashT[1001];
    memset(hashT,0,sizeof(hashT));  //初始化hashT
    int k,cnt = 0;
    for(int i = 0;i < 2;i++){
        scanf("%d",&k);
        int N;
        float ai;
        for(int j = 0;j < k;j++){
            scanf("%d %f",&N,&ai);
            hashT[N] += ai; //遇到幂相等的系数直接相加了
        }
    }
    for(int i = 0;i < 1001;i++){
        if(hashT[i] != 0){
            cnt++;
        }
    }
    printf("%d",cnt);
    for(int i = 1000;i >= 0;i--){
        if(hashT[i] != 0.0){
            printf(" %d %.1f",i,hashT[i]);
        }
    }
    return 0;
}

相比我的算法,在空间上该算法一定是优于我的,在时间上主要取决于n的大小,即k的个数,k越大使用映射法越好。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值