多项式A除以B
这个问题我是在PAT大区赛题里遇见的。题目如下:
多项式A除以B(25 分)
这仍然是一道关于A/B的题,只不过A和B都换成了多项式。你需要计算两个多项式相除的商Q和余R,其中R的阶数必须小于B的阶数。
输入格式:
输入分两行,每行给出一个非零多项式,先给出A,再给出B。每行的格式如下:
N e[1] c[1] ... e[N] c[N]
其中N
是该多项式非零项的个数,e[i]
是第i
个非零项的指数,c[i]
是第i
个非零项的系数。各项按照指数递减的顺序给出,保证所有指数是各不相同的非负整数,所有系数是非零整数,所有整数在整型范围内。
输出格式:
分两行先后输出商和余,输出格式与输入格式相同,输出的系数保留小数点后1位。同行数字间以1个空格分隔,行首尾不得有多余空格。注意:零多项式是一个特殊多项式,对应输出为0 0 0.0
。但非零多项式不能输出零系数(包括舍入后为0.0)的项。在样例中,余多项式其实有常数项-1/27
,但因其舍入后为0.0,故不输出。
输入样例:
4 4 1 2 -3 1 -1 0 -1
3 2 3 1 -2 0 1
输出样例:
3 2 0.3 1 0.2 0 -1.0
1 1 -3.1 题目的意思很明确,就是要求 anxn+an-1xn-1+
an-2xn-2
+。。。
+
a1x1
+
a0x0 除以
amxm+
am-1xm-1+
am-2xm-2
+。。。
+
a1x1
+
a0x0 的商和余数。这可以类比多项式除法进行。
这题的样例数据可表示为:x4-3x2-x-1 除以 3x2-2x+1 求其的商和余数。 手工计算步骤就是下图所示:
依次乘一个(1/3)x2,(2/9)x,(-26/27),很明显就是想办法消掉最高次项,知道所剩的余项最高次小于除数的最高次。

分数化简后就为答案。(上方为商,下方为余数)。
算法核心部分上面已经讲了,接下来讲一下数据结构的设置。
因为每一项都是指数、系数这两个变量,所以我们可以用STL中的map来存储这一个<指数,系数>键值对。
因此我在此设了三个map数组
map<int,double> a; //多项式A(最后的余数)
map<int,double> b; //除数
map<int,double> c; //商
多项式A的初始化
cin>>lena; //A多项式的项数
for(int i=;i<lena;i++){
int e;
double c;
cin>e;
cin>>c;
maxe_a = max(maxe_a,e);//找到A的最高次指数
a[e] = a[e] + c; //相同系数即刻合并
}
多项式B同理,但要注意多求一个最小项次数。
接下来,最重要的来了,那就是除法运算的过程。首先我们先知道要进行几次除法的运算。由上面的示例步骤我们可以知道,运算次数为:( A的最高次幂 - B的最高次幂 )+ 1 次,也可理解为( i = max (eA); i >= max(eB); i --)这样的过程。
商的其中一项就是(当前A的最高次幂系数 / B的最高次幂系数)这是系数,指数为 (当前A的最高次幂 - B的最高次幂),为什么加一个当前呢?因为A每次最高项都会被(B的最高次项 * 相应商的一项)所消掉,直至A最终变为要求的余数项为止。
余数项,就是A每一项每次被 (B的每项 * 相应项的商)做差后系数没被削成0的项。
for(int i = maxe_a;i>=maxe_b;i--){
if(b[maxe_b]!=){
div = 1.0*a[i]/b[maxe_b];
//printf("div=%.1lf\n",div);
sub = i - maxe_b;
c[sub] = div;
maxe_c = max(maxe_c,sub); //求商的最高次幂
//每次从剩余项的最高次开始,直到B的最低次,每项做差
for(int j=i;j>=mine_b;j--){
if(j-sub >= ){
a[j] = a[j] - b[j-sub]*c[sub];
}
}
}
}
之后c[ ] 就是商,a[ ] 就是余数项。
最后依据题意,为c[ ]数组 a[ ]数组做下四舍五入。接下来讲一下怎么做四舍五入。
因为题目要求保留一位有效数字,所以就先把这个数*10化为(int)+/-0.5,再除以10即可。今后碰见四舍五入问题一次类推!
for(int i=maxe_c;i>=;i--){
//四舍五入处理
c[i] = (double)((int)(c[i]* + (c[i]<?-0.5:0.5)))/;
if(c[i]){
cnt++;
}
}
最后奉上此题解的原码:
#include<cstdio>
#include<iostream>
#include<map>
#include<algorithm>
#include<cmath>
using namespace std; map<int,double> a;
map<int,double> b;
map<int,double> c;
int lena,lenb; int main(){
int maxe_a = ,mine_b=,maxe_b=,maxe_c=;
double div;
int sub;
cin>>lena;
for(int i=;i<lena;i++){
int e;
double c;
cin>>e;
cin>>c;
maxe_a = max(maxe_a,e); //找到A的最高次指数
a[e] = a[e] + c; //相同系数即刻合并
}
cin>>lenb;
for(int i=;i<lenb;i++){
int e;
double c;
cin>>e;
cin>>c;
mine_b = min(mine_b,e); //找到B的最低次指数
maxe_b = max(maxe_b,e); //找到B的最高次指数
b[e] = b[e] + c; //相同系数即刻合并
}
for(int i = maxe_a;i>=maxe_b;i--){
if(b[maxe_b]!=){
div = 1.0*a[i]/b[maxe_b];
//printf("div=%.1lf\n",div);
sub = i - maxe_b;
c[sub] = div;
maxe_c = max(maxe_c,sub); //求商的最高次幂
for(int j=i;j>=mine_b;j--){ //每次从剩余项的最高次开始,直到B的最低次,每项做差
if(j-sub >= ){
a[j] = a[j] - b[j-sub]*c[sub];
}
}
}
}
int cnt=;
for(int i=maxe_c;i>=;i--){
c[i] = (double)((int)(c[i]* + (c[i]<?-0.5:0.5)))/;//四舍五入处理
if(c[i]){
cnt++;
}
}
if(cnt ==){
printf("0 0 0.0\n");
}else{
printf("%d",cnt);
for(int i=maxe_c;i>=;i--){
if(c[i]){
printf(" %d %.1lf",i,c[i]);
}
}
printf("\n");
}
cnt =;
for(int i = maxe_a;i>=;i--){
a[i] = (double)((int)(a[i]* + (a[i]<?-0.5:0.5)))/;//四舍五入处理
if(a[i]){
cnt++;
}
}
if(cnt ==){
printf("0 0 0.0");
}else{
printf("%d",cnt);
for(int i=maxe_a;i>=;i--){
if(a[i]){
printf(" %d %.1lf",i,a[i]);
}
}
}
return ;
}
最后总结一下,像这题可以作为多项式相除的模板题目。以后还可用于多项式的因式分解,求方程根等问题。
多项式A除以B的更多相关文章
- L2-018. 多项式A除以B*
L2-018. 多项式A除以B 参考博客 #include <iostream> #include <map> #include <cmath> #include ...
- 7-10 多项式A除以B (25分)(多项式除法)
7-10 多项式A除以B (25分) 这仍然是一道关于A/B的题,只不过A和B都换成了多项式.你需要计算两个多项式相除的商Q和余R,其中R的阶数必须小于B的阶数. 输入格式: 输入分两行,每行给出 ...
- (转载) 天梯赛 L2-018. 多项式A除以B
题目链接 题目描述 这仍然是一道关于A/B的题,只不过A和B都换成了多项式.你需要计算两个多项式相除的商Q和余R,其中R的阶数必须小于B的阶数. 输入格式: 输入分两行,每行给出一个非零多项式,先给出 ...
- 团体程序设计天梯赛 L2-018. 多项式A除以B(模拟)
题意:给你A,B两个多项式,问你A/B的值:注意多项式给你的是每个式子的指数与系数:保留到一位小数,如果出现系数为0(保留后也是)的情况,请不要输出它,如果没有非系数为0的情况就输出特殊 题解:多项式 ...
- L2-018 多项式A除以B(模拟)
这仍然是一道关于A/B的题,只不过A和B都换成了多项式.你需要计算两个多项式相除的商Q和余R,其中R的阶数必须小于B的阶数. 输入格式: 输入分两行,每行给出一个非零多项式,先给出A,再给出B.每行的 ...
- 7-10 多项式A除以B (25 分)
题目链接:https://pintia.cn/problem-sets/1108548596745592832/problems/1108548661014913033 题目大意: 这仍然是一道关于A ...
- pta l2-18(多项式A除以B)
题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805060372905984 题意:给定两个多项式,求出其做除法 ...
- CCCC L2-018. 多项式A除以B 直接上map,然后stack处理输出
https://www.patest.cn/contests/gplt/L2-018 题意:模拟多项式除法. 题解:短除法,初中奥数老师,高中数学老师,高数老师都讲过2333. 模拟之前,关于保存 多 ...
- PAT L2-018. 多项式A除以B
暴力,模拟. 比赛搞了一个小时搞到了$1$分.赛场上不够冷静......之前没接触过多项式除法,但赛场上想到了除法的规则,莫名其妙写的时候不知道哪里崩了.对于这样的题目,应该先测一测数据的指数是不是很 ...
随机推荐
- 控制器没有足够的带宽可利用为USB大容量存储设备的解决方法
伴随网盘时代的没落,最近刚入手了一个移动硬盘.现在的移动硬盘都是USB3.0,传输速度比USB2.0要快很多.但是链接笔记本电脑后发现传输速度在20MB/s左右,跟USB2.0速度差不多,并不能达到传 ...
- [PHP]接口请求校验的原理
具体的校验步骤可以自定义,下面是比较直观的一种形式: 1. 客户端:请求参数带上时间,进行首字母排序,连接私钥后,取得加密结果: 客户端请求时带上这个加密结果作为sign参数. 2. 服务端:对sig ...
- Python学习一:基础语法
---恢复内容开始--- 本博客主要记录学习Python的过程(按照金角大王老师课程学习),整理所学知识,扎实基础.如有错误,望批评指正. 1.Python所擅长的领域 Python是一门解释型语言, ...
- 解决AspNet Zero Core 5.0.1无法运行的问题
最近在研究AspNet Zero Core 5.0.1时发现VS点击调试后就自动退出了,从ABP QQ群里得知作者加入了licensecode校验.经过一个周左右断断续续的折腾,算是破解了吧.原本想把 ...
- 使用.bat来执行Java程序基础
将java程序做成可运行的jar后,又希望使用.bat文件来调用jar时,有几点需要注意的. 1.设置path和classpath .bat文件中扥的内容如下: @echo off set MY_HO ...
- 夏令营讲课内容整理 Day 2.
本日主要内容是并查集和堆. 并查集 并查集是一种树型的数据结构,通常用来处理不同集合间的元素之间的合并与查找问题.一个并查集支持三个基本功能:合并.查找和判断.举一个通俗的例子,我和lhz认识,lhz ...
- SDN第四次作业
作业链接 1.阅读 了解SDN控制器的发展 http://www.sdnlab.com/13306.html http://www.docin.com/p-1536626509.html 了解ryu控 ...
- 【翻译】CSS Animations VS the Web Animations API:案例学习
原文地址:CSS Animations vs the Web Animations API: A Case Study May 03, 2017 css, javascript 上周我写了我如何使用C ...
- java程序设计原则
前言: 前言:java这种面向对象的的语言其实是很符合人的生活思维模式的,因为它以对象作为自己的研究对象,所谓"万物皆对象".一个人.一颗苹果.一只蚂蚁都是对象.所以它的设计原则和 ...
- PHP输出打印方法
PHP这门语言灵活而充满众多的API和用法,然而在这个技术领域里却缺乏一些系统的总结归纳.或许这与PHP语言的诞生方式有关,衍生,快速变化,原始限制等等,诸多因素决定这门语言变得smarty,却没有人 ...