PAT A1002 A+B for Polynomials 多项式相加

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


题目大意:


给两个多项式a,b,输入样式的格式(如a: 2 1 2.4 0 3.2 ):第一个数字n(2),是多项式的非零项数,后面跟着2*n(4)个数字,两两一组,每组的第一个数字代表该项的幂,第二个数字代表该项的系数(1,2.4即为2.4X),一次类推。值得注意的是:按照格式,多项式的输入和输出格式都是按照最高次幂向低次幂的顺序


解题思路:

     每个多项式的幂不超过1000([0,1000]),因此使用一个double数组大小为1001即可满足。读取第一个数字即为项数,使用循环读取后面的内容,幂作为数组的下表,系数作为内容填充数组。第二个数采取同样的办法,只不过一边读取一边判断double数组幂为下标的位置内容是否为零,为零则项数加一。然后加到数组以幂为下标的位置上。

    max和min的作用:纪录double数组中,内容不为零的最小位置(最小幂)和最大位置(最大幂),输出的时候从这个区间遍历,即可以减少程序的运行时间。

    为0判断:由于浮点数在操作系统里面的存储格式,因此判断一个浮点数是否为零,不能简单地直接使用(X==0)这种比较方式,而是使用定义一个允许的误差,如开头定义了误差(#define err 1e-7),如果一个浮点数的绝对值比这个误差要小,那么我们就认为他等于零。 

 

   代码非原创,此文仅纪录思路


 

#define err 1e-7
#include <math.h>
#include <stdio.h>
int main() {
    double a[1001] = {0.0};
    int count = 0, max = 0, min = 0;
    int k;
    double tempA;
    int tempN;
    
    // 读入第一个多项式并存储
    scanf("%d", &k);
    for(int i = 0; i < k; i++){
        scanf("%d %lf", &tempN, &tempA);
        if(i == 0) max = tempN;      //输入从最高次幂向低次幂输入,纪录最大值
        if(i == k - 1) min = tempN;  //纪录最小值
        a[tempN] = tempA;            //以幂为下标的位置纪录其系数
    }
    // 一开始有k项
    count = k;
    
    // 读入第二个多项式的同时直接计算
    scanf("%d", &k);
    for(int i = 0; i < k; i++){
        scanf("%d %lf", &tempN, &tempA);
        // 原来没有这一项,增加后就会多一项
        if(fabs(a[tempN]) < err){
            count++;
            if(tempN > max) max = tempN; //新加入的项可能会改变多项式的最高/低次幂
            else if(tempN < min) min = tempN;
        }
        a[tempN] += tempA;
        
        // 计算结果趋近于0,减少一项
        if(fabs(a[tempN]) < err){
            count--;
        }
    }
    
    // 输出K
    printf("%d", count);
    
    // 输出N和an
    for(int i = max; i >= min; i--){
        if(fabs(a[i]) > err){
            printf(" %d %.1f", i, a[i]);
        }
    }
    return 0;
}

关于第二个循环留下的思考:

if(fabs[a[tempN]]<err)说明幂为tempN的内容为0,约等于没有,所以count+1,表示,我来b来填充这一部分内容了。然后a[tempN]+=tempA,然后在判断if(fabs[a[tempN]]<err)加完了之后还是约等于0,那么我们就认为这一项仍然没有,count要--

那么我的问题来了,我最后判定改成if(fabs[tempA]<err)(为什么这么想,原来约等于没有count++,要加的东西即tempA如果也约等于没有,那最后结果就是约等于没有呗,因此就count--)作为判定条件行不行,答案是不太行。为什么叫不太行呢,就是一部分行,一部分不行。

行在于,整数或者不是很小的小数,你这么去想确实没错

不行在于浮点数,浮点数由于有精度,因此都是近似值,我们假设精度是两位小数,那么0.004表示就是0.00,0.005表示就是0.01

到现在明白了吗,约等于没有不等于真的没有

如果原来是0.008,tempA是0.003,虽然两个数显示的都是0.00约等于没有,但是加起来就是0.011,显示就是0.01了,此时就有了,,,有了!!!!

因此判断有没有,应该整体的对加之前和加之后进行判断

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值