蓝桥杯备赛系列 高精度 acwing版

                                        前言

hello,好久不见。元旦玩过后该收心了,我也倒计时一下蓝桥杯考试时间,大家一起复习,一起登顶。今天讲解高精度算法。

这个算法其实是给学c++同学讲的,因为python自带高精度所以不需要,且我讲到所有内容都是c++版本,今年就要报考c++,今年学好了Java可以上Java内容。

不多bb了上正文

                                        正文

         先介绍一下为什么要用高精度。

  1. int:通常,int 类型的大小是依赖于特定平台的,常见的有 16 位(2 字节)、32 位(4 字节)和 64 位(8 字节)等。在某些平台上,int 可能只有 16 位,能够存储的最大值是 32767;而在其他平台上,int 可能有 32 位或 64 位,能够存储的最大值分别是 2147483647 和 9223372036854775807。
  2. long longlong long 类型通常至少有 64 位,并且能够存储的最大值是 9223372036854775807。实际上,long long 的大小和能够存储的最大值也是依赖于特定平台和编译器的。

所以由此看来如果输入的数过大int 和longlong类型都会爆掉,那我要是硬使用

会怎么样呢,下面这个照片给大家展示一下。

 很明显是不行的,所以要引入高精度这个算法。

高精度如何存数字呢,很明显就是数组。

高精度加法
主要思想:用字符数组进行接收数字,将数字逐一逆序存储到数组中,对应位置依次相加。
在此之前,我们回忆一下小学加法的做法:
1.对应位置相加
2.逢十进一

(1)8+9=17,逢十进一,17%10得到个位存储的数字为7。
(2)4+5+1=10,逢十进一,10%10得到个位存储的数字为0。
(3)两个数字百位都没有数字了,所以百位存储的数字就为1。
(4)得到答案107。

高精度加法步骤:
(1):字符数组存储大数字
(2):逆序插入整形数组
(3):对应位置数字相加,并进行%10运算存储到数组中,逢十进一
(4):将数组数字逆序输出

#include <iostream>
#include <vector>using namespace std;vector<int> add(vector<int> &A, vector<int> &B)
{if (A.size() < B.size()) return add(B, A);vector<int> C;int t = 0;for (int i = 0; i < A.size(); i ++ ){t += A[i];if (i < B.size()) t += B[i];C.push_back(t % 10);//t=a+b eg:t=12,t%10=2 push back  放入c的最后一位t /= 10;//eg:x=12,x/10=1}if (t) C.push_back(t);return C;
}int main()
{string a, b;vector<int> A, B;cin >> a >> b;for (int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');//读入的话是把小数放入a[0]以此类推for (int i = b.size() - 1; i >= 0; i -- ) B.push_back(b[i] - '0');auto C = add(A, B);//auto相当于一种定义类型,这里计算机可以直接判断定义类型for (int i = C.size() - 1; i >= 0; i -- ) cout << C[i];//输出的话我们习惯于把高位放在第一个跟读入的方式相反cout << endl;return 0;
}

(1)设置一个足够大的数N,用于标识数组的长度
(2)创建两个字符数组用于存储高精度数字
(3)创建整形数组
(4)(5)求两个高精度数字的位数
(6)(7)将两个高精度数字逆序存储到整形数组中
(8)存储两个数字中长度更长的
(9)计算新数组的长度
(10)(11)将两个数字对应位置进行相加
(12)将相加得到的数字%10存储到数组中
(13)判断是否需要进1
(14)判断最后是否还需要进1
(15)逆序打印
 

高精度减法
主要思想:用字符数组进行接收数字,将数字逐一逆序存储到数组中,对应位置依次相减。做法和高精度加法类似。
小学减法的做法:
1.对应位置相减,不够相减就向后一位借1

高精度减法步骤:
(1):字符数组存储大数字
(2):逆序插入整形数组
(3):对应位置数字相减,并判断当前所在位的被减数是否需要借1
(4):将数组数字逆序打印
 

#include <iostream>
#include <vector>using namespace std;bool cmp(vector<int> &A, vector<int> &B)
{if (A.size() != B.size()) return A.size() > B.size();for (int i = A.size() - 1; i >= 0; i -- )if (A[i] != B[i])return A[i] > B[i];return true;
}vector<int> sub(vector<int> &A, vector<int> &B)
{vector<int> C;for (int i = 0, t = 0; i < A.size(); i ++ ){t = A[i] - t;if (i < B.size()) t -= B[i];C.push_back((t + 10) % 10);if (t < 0) t = 1;else t = 0;}while (C.size() > 1 && C.back() == 0) C.pop_back();return C;
}int main()
{string a, b;vector<int> A, B;cin >> a >> b;for (int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');for (int i = b.size() - 1; i >= 0; i -- ) B.push_back(b[i] - '0');vector<int> C;if (cmp(A, B)) C = sub(A, B);else C = sub(B, A), cout << '-';for (int i = C.size() - 1; i >= 0; i -- ) cout << C[i];cout << endl;return 0;
}

(1)设置一个足够大的数N,用于标识数组的长度
(2)创建两个字符数组,用于接收高精度数字
(3)创建两个整形数组,用于逆序存储高精度数字
(4)接收相减的结果
(5)将大数字逆序插入到整形数组中
(6)比较两个高精度数字的长度,用于后面消除前导0
(7)比较两个高精度数字的大小
(8)模拟减法竖式运算
(9)对应位置数字相减
(10)将相减得到的结果插入到数组中
(11)判断是否需要向后一位借1
(12)去除前导0
(13)逆序打印结果

高精度乘法

主要思想:依旧是模拟小学的乘法运算,使用字符数组存储大数字,再逆序存储到整形数组中。
小学乘法的做法:
1.对应位置相乘
2.对相乘的结果%10加到后一位

这里我们进行乘法的模拟运算:

 

通过该图我们发现:
a0b0对应C1的位置
a1b0对应C1的位置
a2b0对应C2的位置
a3b0对应C3的位置
a0b1对应C1的位置
a1b1对应C2的位置
a2b1对应C3的位置
a3b1对应C4的位置
由此可以归纳出来一个规律
C[i+j]=a[i]*a[j]
由此也可得出进位等于C[i+j+1]

高精度乘法的步骤:
(1):字符数组存储大数字
(2):逆序插入整形数组
(3):对应位置数字相乘,相乘结果进行%10运算,并加到后一位上。
(4):将数组数字逆序打印
 

#include <iostream>
#include <vector>using namespace std;vector<int> mul(vector<int> &A, int b)
{vector<int> C;int t = 0;for (int i = 0; i < A.size() || t; i ++ ){if (i < A.size()) t += A[i] * b;C.push_back(t % 10);t /= 10;}while (C.size() > 1 && C.back() == 0) C.pop_back();//考虑b=0的情况的,如果b!=0就不用加return C;
}int main()
{string a;int b;cin >> a >> b;vector<int> A;for (int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');auto C = mul(A, b);for (int i = C.size() - 1; i >= 0; i -- ) printf("%d", C[i]);return 0;
}

(1)设置一个足够大的数N,用于标识数组的长度。
(2)创建两个字符数组用于存储高精度数字。
(3)创建整形数组。
(4)将数字逆序插入数组中
(5)对所得结果%10进行进位操作
(6)相乘得到的结果需要进行%10才能存储到数组中
(7)去除前导0
(8)逆序打印数字
 

高精度除法

主要思想:依旧是模拟小学的除法运算,使用字符数组存储大数字,再存储到整形数组中。(这里插入到数组中,不是逆序插入!)

(1)4/12不够除,所以第一位商0
(2)42/12商3余3
(3)33/12商2余9
所以答案就为32余9
这里的过程为:
4/12,不够除
410+12=42 ,42/12=3,这位余下了一个3
310+3==33 , 33/12=2,被除数每一位都走完,除法结束。余数为0
可以得到规律:
前一位的余数*10+当前位的数字/除数=商

高精度除法步骤:
(1):字符数组存储大数字
(2):正序插入整形数组
(3):计算上一位的余数*10+当前位的数字/除数的结果
(4):计算当前位的余数
(5):将数组数字逆序打印
 

#include <iostream>
#include <vector>
#include <algorithm>using namespace std;vector<int> div(vector<int> &A, int b, int &r)
{vector<int> C;r = 0;for (int i = A.size() - 1; i >= 0; i -- ){r = r * 10 + A[i];C.push_back(r / b);r %= b;}reverse(C.begin(), C.end());while (C.size() > 1 && C.back() == 0) C.pop_back();return C;
}int main()
{string a;vector<int> A;int B;cin >> a >> B;for (int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');int r;auto C = div(A, B, r);for (int i = C.size() - 1; i >= 0; i -- ) cout << C[i];cout << endl << r << endl;return 0;
}

(1)创建一个足够大的N为数组分配空间
(2)创建一个字符串数组用于存储大数字
(3)(4)创建两个整形数组,一个用于存储大数字,一个用于存储结果
(5)存储低精度数字
(6)将大数字按正常顺序存储数组中
(7)因为是第一位,没有上一位,所以余数t一开始设置为0
(8)当前位的数字加上上一位的余数*10,再除以除数
(9)计算当前位的余数
(10)去除前导0
(11)顺序打印结果
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/327682.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Wrk压测发送Post请求的正确姿势

一、Wrk简介 wrk 是一个能够在单个多核 CPU 上产生显著负载的现代 HTTP 基准测试工具。它采用了多线程设计&#xff0c;并使用了像 epoll 和 kqueue 这样的可扩展事件通知机制。此外&#xff0c;用户可以指定 LuaJIT 脚本来完成 HTTP 请求生成、响应处理和自定义报告等功能。 …

频率域滤波图像复原之逆滤波的python实现——数字图像处理

逆滤波原理 逆滤波是一种在频率域进行的图像复原技术&#xff0c;常用于修复由运动模糊等因素引起的图像退化。具体步骤如下&#xff1a; **频率域表示&#xff1a;**首先&#xff0c;将退化的图像通过傅里叶变换从空间域转换到频率域。这使得图像的频率成分变得明显&#xf…

直流稳压电源电路

一、稳压电源的技术指标及对稳压电源的要求 稳压电源的技术指标可以分为两大类&#xff1a;一类是特性指标&#xff0c;如输出电压、输出电滤及电压调节范围;另一类是质量指标&#xff0c;反映一个稳压电源的优劣&#xff0c;包括稳定度、等效内阻&#xff08;输出电阻&#x…

dyld: Library not loaded: /usr/lib/swift/libswiftCoreGraphics.dylib

更新Xcode14后低版本iPhone调试报错 dyld: Library not loaded: /usr/lib/swift/libswiftCoreGraphics.dylib Referenced from: /var/containers/Bundle/Application/…/….app/… Reason: image not found 这是缺少libswiftCoreGraphics库 直接导入libswiftCoreGraphics库即…

软件测试作业‖pytest+po+csv+html报告+cookie+selenium

软件测试作业‖pytestpocsvhtml报告cookieselenium 先用本地部署的系统试了下 或者UFT自动化测试里诺图书管理系统软件测试 # &#xff0c;#测试报告# #性能测试#&#xff0c;#测试用例#&#xff0c; #自动化测试# Selenium 的 Web自动化测试基本要求和注意事项 1.请使用ch…

软件测试之单元测试、系统测试、集成测试知识总结

一、单元测试的概念 单元测试是对软件基本组成单元进行的测试&#xff0c;如函数或一个类的方法。当然这里的基本单元不仅仅指的是一个函数或者方法&#xff0c;有可能对应多个程序文件中的一组函数。 单元也具有一些基本的属性。比如&#xff1a;明确的功能、规格定义&#…

phpstudy面板Table ‘mysql.proc‘ doesn‘t exist解决办法

原因分析&#xff1a;误删了mysql数据库 解决办法如下&#xff1a; 1、停止服务 2、先把mysql文件夹下的data文件夹备份&#xff0c;因为data文件里存有数据库文件。然后再删除data文件。 3、cmd管理员命令进入到mysql中的bin目录下 &#xff0c;执行mysqld --initialize-…

2024--Django平台开发-基础信息(一)

一、前置知识点 - Python环境搭建 (Python解释器、Pycharm、环境变量等) - 基础语法(条件、循环、输入输出、编码等) - 数据类型(整型、布尔型、字符串、列表、字典、元组、集合等) - 函数(文件操作、返回值、参数、作用域等) - 面向对象 (类、对象、封装、继承、多态等)包和模…

Vue3-39-路由-导航异常的检测 afterEatch 与 编程式导航之后的订阅动作

说明 本文主要是介绍一下 路由的后置守卫 afterEatch 的一个重要的作用 &#xff1a; 就是检测路由异常信息。 它的实现方式是 通过第三个参数来返回的。 而且&#xff0c;它的异常检测是全局的。导航的异常有以下三种类型&#xff1a; aborted : 在导航守卫中 被拦截并返回了…

certbot https 证书配置

服务器上敲这个命令 certbot certonly --manual --preferred-challenges dns -d 51dbapi.com,*.51dbapi.com会弹出这个。点击回车 然后去域名页面配置新的解析记录 就可以了&#xff0c;3个月搞一次&#xff0c;自动的没配成功过&#xff0c;就手动吧

HarmonyOS4.0系统性深入开发15Want概述

Want概述 Want的定义与用途 Want是对象间信息传递的载体&#xff0c;可以用于应用组件间的信息传递。其使用场景之一是作为startAbility()的参数&#xff0c;包含了指定的启动目标以及启动时需携带的相关数据&#xff0c;如bundleName和abilityName字段分别指明目标Ability所…

故障诊断 | 基于FFT频谱与小波时频图的双流CNN轴承故障诊断模型(matlab +python)

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 故障诊断 | 基于FFT频谱与小波时频图的双流CNN轴承故障诊断模型&#xff08;matlab python&#xff09; 基于FFT频谱与小波时频图的双流CNN轴承故障诊断模型 特征拼接 python&#xff08;pytorch&#xff09; 基于2D-…