PTA L2-018 多项式A除以B
- 题目网址:https://pintia.cn/problem-sets/994805046380707840/exam/problems/994805060372905984
-
题目概述:
这一道题首先得知道多项式除法,怎么弄得,这个高中其实都学过,在分解多项式那一个环节。这道题每次都拿除多项式的最高次幂(阶数)项去消掉被除多项式,而后剩下的项则与被除多项式进行相加减。
- 存储结构:
- 采用下标记录阶数,里面的值记录系数。
- 开一个差不多1000000的数组够用了,针对本题。
- 注意事项:
- 我们可以直接用浮点数来进行计算,没必要用分数,c++浮点数能存储5位(好像是),足够我们判断是否需要舍去。对于输出无论用
还是cout
都可以,保留一位小数即可,注意这里只对那些大于等于printf
的数进行保留。0.05
- 注意只有当被除多项式的最高阶数大于等于除多项式的阶数时才可以进行除法,否则商直接就是0多项式,而余数直接就是原来的被除多项式。(这种情况不需要进行舍入,因为系数都是整数)
- 可以除的情况下,每次都需要知道当前所做除法的被除数最高阶数是多少,其实就直接从被除数最高阶开始递减,只要阶数对应下标所存储的值不为0,说明被除数这边有值从而进行除法(题目所给的数据是阶数是递减的,不存在一个阶数出现两次的情况,所以在运算过程中被除数一直在变化,阶数一直在递减)
- 可以除的情况下:设置循环
当前情况的被除数阶数大于等于除数,从最高阶开始,对存储被除数的数组开始进行操作,max1为当前情况被除数的最高阶,max2始终就是除数的最高阶,求出max1-max2的值(max1!=0),就更改被除数数组,存储商 = 当前情况被除数最高阶系数 / 除数最高阶系数。while(max1>=max2)
- 注意对于除法过程中不需要先进行判断是否舍去,从除法结束后开始。
- 除法结束后,必须要知道商和余数符合输出条件的个数,不然为0的话需要直接输出0多项式。记住,这里的商和余数都需要进行判断。得到个数后再进行一遍循环判断并输出。
- 我们可以直接用浮点数来进行计算,没必要用分数,c++浮点数能存储5位(好像是),足够我们判断是否需要舍去。对于输出无论用
- 关于测试点:
- 没有被除数为0多项式的测试案例,除数也没有为0多项式。(不然输入的形式都得再加一层判断)
- 测试点4:必须要判断商的系数的是否大于等于0.05。
- 代码(上面语言有点粗糙,大家看代码应该能看懂)
#include <iostream> #include <iomanip> using namespace std; double xishu1[10000000], xishu2[10000000]; double outxishu1[10000000]; int main() { double x = 0.05; cout << setiosflags(ios::fixed) << setprecision(1); int N1 = -1, N2 = -1; int max1, max2; int countRemainNum = 0, countDivNum = 0; int temp; int maxE; //记录被除数的最大次数,不会变这个值。 int dis = 0; cin >> N1; for (int i = 1; i <= N1; i++) { cin >> temp; cin >> xishu1[temp]; if (i == 1) { max1 = temp; // 底下出发循环再变 maxE = max1; // 不变的 } } cin >> N2; for (int i = 1; i <= N2; i++) { cin >> temp; cin >> xishu2[temp]; if (i == 1) { max2 = temp; } } // 直接被除数小于除数的情况 if (max1 < max2) { int y = 0; cout << y << " " << y << " " << 0.0 << endl; countDivNum = N1; cout << N1 << " "; for (int i = max1; i >= 0; i--) { if (abs(xishu1[i]) > 0) { cout << i << " " << xishu1[i]; countDivNum--; if (countDivNum > 0) { cout << " "; } } } return 0; } // 正常情况,被除数大于除数的情况 double xishu; // 一旦被除数的最大系数小于除数的最大系数时,除法结束。 while (max1 >= max2) { if (xishu1[max1] == 0) { max1--; continue; } // dis就是此次运算阶数的差值,作为outxishu1数组的下标。 dis = max1 - max2; xishu = xishu1[max1] / xishu2[max2]; // 得到商中能够输出的个数(也可以除法结束后再遍历存储商的数组outxishu1进行判断计数) if (abs(xishu) >= x) { outxishu1[dis] = xishu; countDivNum++; } // 开始更新被除数的值以及max1 , 直接抵消的此时的被除数最高项可不做处理。但是保险一点还是处理一下为0。 // 而且xishu2中可能存在着0,但是没关系,乘0相减还是0。 for (int j = 0; j <= max2; j++) { xishu1[j + dis] -= (xishu2[j] * xishu); } xishu1[max2 + dis] = 0; max1--; } cout << countDivNum << " "; int timeR = countDivNum; // **************************【就是这一步骤!!!】******************************** // 就算被除数次数大于除数,也有可能出现商为0的情况,因为商的各项数值可能都小于0.05 if (countDivNum == 0) { int y = 0; cout << y << " " << 0.0 << endl; } else { for (int i = maxE - max2; i >= 0; i--) { if (abs(outxishu1[i]) >= x) { cout << i << " " << outxishu1[i]; timeR--; if (timeR > 0) { cout << " "; } } } cout << endl; } // 被除数小于除数时,此时这代码不执行 // 余数中能够输出的个数 for (int j = max2 - 1; j >= 0; j--) { if (abs(xishu1[j]) >= x) { countRemainNum++; } } cout << countRemainNum << " "; int time = countRemainNum; if (countRemainNum == 0) { int y = 0; cout << y << " " << 0.0 << endl; } else { for (int j = max2 - 1; j >= 0; j--) { if (abs(xishu1[j]) >= x) { cout << j << " " << xishu1[j]; time--; if (time > 0) { cout << " "; } } } cout << endl; } return 0; } /* 测试数据 0 0 0.0 3 2 3 1 -2 0 1 2 1 3 0 -1 3 2 3 1 -2 0 1 2 2 4 1 2 2 1 2 0 1 */