C++:第十五讲高精度算法

每日C++知识

 system("color xx);是改变字体及背景颜色,前一个x代表一个数字,可以改变背景颜色,后一个x代表一个数字,可以改变字体颜色 ,但都是根据颜色表来的。

记住:要加头文件:#include<windows.h>

颜色对照表: 
0 = 黑色
1 = 蓝色
2 = 绿色
3 = 湖蓝色
4 = 红色
5 = 紫色
6 = 黄色
7 = 白色
8 = 灰色
9 = 亮蓝色
A = 亮绿色
B = 亮湖蓝色
C = 亮红色
D = 亮紫色
E = 亮黄色
F = 亮白色 

例子:

#include<bits/stdc++.h>
#include<windows.h> 
using namespace std;
int main(){system("color 01");cout<<"1234567890"; return 0;
}

输出结果:

 

高精度简介

在C++中当你用int、long long,甚至是unsigned long long 都无法处理的超级巨大数字,你会感到无比痛苦甚至到绝望,那么我们此时就只有一种方法了——高精度算法。我们可以利用程序设计的方法去实现这样的高精度计算。介绍常用的几种高精度计算的方法。本文主要实现的是自然数范围内做运算的 加法、减法、乘法、除法 四种基本高精度运算。

高精度(High Precision)是一种在计算机编程中用于表示和操作大数的技术。在C++中,可以使用高精度思想来处理大数,例如质数、因数分解等。

(1)高精度加法,所用到的算法很简单,其实就是我们小学所学的加法“竖式”计算。将两个加数的对应数位对齐,也就是说个位对个位、十位对十位、百位对百位,对应的数位进行加法操作,有进位的要进位。

(2)高精度加法要将两个加数按对应的位数一位一位地处理,所以在实践中,将两个加数分别用两个数组进行存储,问题就会变得简单。

(3)之前我们已经说过,C++中最大的整数是long long型,最大位数是20位。所以对于10000位的正整数,我们输入的数据类型应该是一个字符串,也就是string型的数据。

例题1洛谷P1303 A*B Problem

题目描述

给出两个非负整数,求它们的乘积。

输入格式

输入共两行,每行一个非负整数。

输出格式

输出一个非负整数表示乘积。

输入输出样例

输入 #1

1
2

输出 #1

2

说明/提示

每个非负整数不超过10的2000次方

解题思路

在讲这道题之前,我有必要先从高精度加/减法来引入一下。

高精度加减法最重要的是什么?当然是对齐数位了!那么,为了达到这一点,我们不惜要先将输入倒序存储,高精乘也是这样。下面,拿一张表格来示意一下高精度加法的运算过程:

20056
+19023
=39079

那么高精乘呢?他们也需要判定位置关系,只不过关系表达式用坐标表示是这样的:a[i]*b[j]==c[i,j]//乘数 * 乘数=乘积。

AC

#include<bits/stdc++.h>
using namespace std;
char a1[10001],b1[10001];
int a[10001],b[10001],i,x,len,j,c[10001];
int main ()
{cin>>a1>>b1;int lena=strlen(a1);int lenb=strlen(b1);for(i=1;i<=lena;i++)a[i]=a1[lena-i]-'0';for(i=1;i<=lenb;i++)b[i]=b1[lenb-i]-'0';for(i=1;i<=lenb;i++)for(j=1;j<=lena;j++)c[i+j-1]+=a[j]*b[i];for(i=1;i<lena+lenb;i++)if(c[i]>9){c[i+1]+=c[i]/10;c[i]%=10;}len=lena+lenb;while(c[len]==0&&len>1)len--;for(i=len;i>=1;i--)cout<<c[i];return 0; 
}

例题2洛谷P1480 A/B Problem

题目描述

输入两个整数 a,b,输出它们的商。

输入格式

两行,第一行是被除数,第二行是除数。

输出格式

一行,商的整数部分。

输入输出样例

输入 #1

10
2

输出 #1

5

说明/提示

0≤a≤10的5000次方,1≤b≤10的9次方。

解题思路

这是一道高精除低精模板题。

模拟竖式被除数的每一位加上余数除以被除数并更新余数的过程即可。

不过要注意一下:在数 a 后面拼上一位数 b 是 10a+b。

自己推一下竖式就可以理解了。

记得最后要去除前导零。

AC

#include <iostream>
using namespace std;
string a, res;
long b;
int main() {cin >> a >> b;long t = 0;for (int i = 0; i < a.size(); i++) {res.push_back((t * 10 + a[i] - '0') / b + '0');t = (t * 10 + a[i] - '0') % b;}int i = 0;while (i + 1 < res.size() && res[i] == '0') i++;cout << res.substr(i) << endl;
}

例题3洛谷P1601 A+B Problem

题目描述

高精度加法,相当于 a+b problem,不用考虑负数

输入格式

分两行输入。a,b≤10的500次方。

输出格式

输出只有一行,代表 a+b 的值。

输入输出样例

输入 #1

1
1

输出 #1

2

输入 #2

1001
9099

输出 #2

10100

说明/提示

20% 的测试数据,0≤a,b≤10的9次方;

40% 的测试数据,0≤a,b≤10的18次方。

解题思路

A+B高精度版其实是一道模板题,在很多领域都有用处。

高精度算法,属于处理大数字的数学计算方法。在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几千亿几百亿的大数字。一般这类数字我们统称为高精度数,高精度算法是用计算机对于超大数据的一种模拟加,减,乘,除,乘方,阶乘,开方等运算。

AC

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
void add(char a[], char b[])
{//获取数组长度int alen = strlen(a), blen = strlen(b), t = 0, i,len;// 翻转数组,为了低位对齐reverse(a,a+alen);reverse(b,b+blen);// 存放·结果int c[502]={0};// 取较短的位len = (alen < blen) ? alen : blen;// 对应位相加for (i = 0; i <len; i++){c[i]=((a[i]+b[i]-'0'-'0')+t);// t代表进位t=c[i]/10;c[i]=c[i]%10;}// 剩余位处理while (i<alen){c[i]=t+(a[i]-'0');t=c[i]/10;c[i]=c[i]%10;i++;}while (i<blen){c[i]=t+(b[i]-'0');t=c[i]/10;c[i]=c[i]%10;i++;}// 最高位进位if(t!=0){c[i]=t;i++;}// 输出for(i=i-1; i >= 0; i--) printf("%d", c[i]);
}
int main()
{char a[502]={0}, b[502]={0};scanf("%s %s", a, b);add(a,b);return 0;
}

课后练习P1080 [NOIP2012 提高组] 国王游戏

题目描述

恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 n 位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。

国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。

输入格式

第一行包含一个整数 n,表示大臣的人数。

第二行包含两个整数 a 和 b,之间用一个空格隔开,分别表示国王左手和右手上的整数。

接下来 n 行,每行包含两个整数 a 和 b,之间用一个空格隔开,分别表示每个大臣左手和右手上的整数。

输出格式

一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的金币数。

输入输出样例

输入 #1

3
1 1
2 3
7 4
4 6 

输出 #1

2

说明/提示

【输入输出样例说明】

按 1、2、3 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;

按 1、3、2 这样排列队伍,获得奖赏最多的大臣所获得金币数为2;

按 2、1、3 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;

按2、3、1这样排列队伍,获得奖赏最多的大臣所获得金币数为 9;

按 3、1、2这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;

按3、2、1 这样排列队伍,获得奖赏最多的大臣所获得金币数为 9。

因此,奖赏最多的大臣最少获得 2个金币,答案输出2。

【数据范围】

对于 20%的数据,有 1≤n≤10,0<a,b<8;

对于 40%的数据,有1≤n≤20,0<a,b<8;

对于 60%的数据,有 1≤n≤100;

对于 60%的数据,保证答案不超过 10的9次方;

对于 100%的数据,有 1≤n≤1,000,0<a,b<10000。

解题思路

其实懂了思想还是挺简单的,朴素的高精度乘法和高精度除法,但难想到的还是如何一开始给他们排序,于是冥思苦想,终于发现了如何排序(好吧,借鉴了别人的想法),便是按a*b排序。

为什么呢?我简单说明一下,假设前面几个人都排好了,我们要如何证明最后两个人谁排前面会对答案影响小一点呢?也就是贡献得尽量小一点,设前几个人a的乘积为x,那么这两个人(a1,b1)和(a2,b2)谁排前一个结果就为x*a1/b2和x*a2/b1,将他们做下比较,易得出当a1*b1<a2*b2时(a1,b1)排在前面更好【可以在草稿纸上列下不等式算下,不难得出】,然后就简单了!

AC

#include<bits/stdc++.h>
#define ll long long
#define ld long double
using namespace std;
string hmul(string a,string  b){int c[500005];memset(c,0,sizeof c);int x[a.size()],y[b.size()];memset(x,0,sizeof x);memset(y,0,sizeof y);for(unsigned int i=0;i<a.size();i++)x[a.size()-1-i]=a[i]-'0';for(unsigned int i=0;i<b.size();i++)y[b.size()-i-1]=b[i]-'0';for(unsigned int i=0;i<a.size();i++){for(unsigned j=0;j<b.size();j++){c[i+j]+=x[i]*y[j];}}for(unsigned int i=0;i<a.size()+b.size();i++){if(c[i]>=10){c[i+1]+=c[i]/10;c[i]%=10;}}string ci;bool p=1;for(int i=a.size()+b.size()-1;i>=0;i--){if(c[i]==0&&p) continue;else{p=0;ci+=c[i]+'0';}}return ci;
}
string hdiv(string a,int b){int x[50005];int y[50005];memset(x,0,sizeof(x));memset(y,0,sizeof(y));for(unsigned int i=0;i<a.size();i++){x[i+1]=a[i]-'0';}int yu=0;for(unsigned int i=1;i<=a.size();i++){y[i]=(yu*10+x[i])/b;yu=(yu*10+x[i])%b;}int kk=1;while(y[kk]==0&&kk<a.size()) kk++;string aa;for(unsigned int i=kk;i<=a.size();i++){aa+=y[i]+'0';}return aa;
}
string smx(string a,string b){if(a.size()!=b.size()) return a.size()>b.size()?a:b;return a>b?a:b;
}
string tur_str(int num){string str;while(num){str+=num%10+'0';num/=10;}reverse(str.begin(),str.end());return str;
}
int n;
struct aa{int l,r;
}a[100005];
bool cmp(aa a,aa b){return (a.l*a.r)<(b.l*b.r);
}
int main(){cin>>n;cin>>a[0].l>>a[0].r;for(int i=1;i<=n;i++) cin>>a[i].l>>a[i].r;sort(a+1,a+n+1,cmp);string ans="0";string xx=tur_str(a[0].l);for(int i=1;i<=n;i++){ans=smx(ans,hdiv(xx,a[i].r));//cout<<"ans=="<<ans<<endl;xx=hmul(xx,tur_str(a[i].l));}cout<<ans<<endl;return 0;
}

结尾

希望大家多多关注!!!

本篇文章共5996字,如果你能支持一下我,我十分感谢!!!

如果有人想在洛谷上做题,可以点下方链接:

https://www.luogu.com.cn/

如果你喜欢或想了解一下其他的算法,可以看看以下这些:

题目详解系列(部分):

【万题详解】洛谷P1252 马拉松接力赛-CSDN博客

【万题详解】洛谷P1359 租用游艇-CSDN博客

【百题详解】洛谷P8508 做不完的作业-CSDN博客

【万题详解1】洛谷P1230 智力大冲浪-CSDN博客

【全网首发】洛谷贪心题解集合-CSDN博客

洛谷二分题集(3题)-CSDN博客

游戏系列:

C++:史上最坑小游戏-CSDN博客

 C++:自创小游戏-CSDN博客

C++:下雪-CSDN博客

C++讲解系列(算法):

C++:第十二讲DFS深搜(二)_c++匿名函数dfs-CSDN博客

 C++:第十一讲DFS深搜-CSDN博客

C++:第十讲二分查找-CSDN博客

前缀和与差分:

C++:第九讲前缀和与差分-CSDN博客

贪心:

C++:第八讲贪心算法1-CSDN博客

C++讲解系列(基础入门):

排序:

C++:第七讲冒泡排序-CSDN博客

函数:

C++第6讲max和min函数_c++ min函数-CSDN博客

C++第五讲函数初步-CSDN博客

for循环&数组:

C++第四讲for循环及数组-CSDN博客

if语句&else语句及运算:

C++第三讲:C++中的逻辑运算符及if else语句-CSDN博客

基础:

C++第二讲输入与输出-CSDN博客

C++第一讲认识C++编译器-CSDN博客

欢迎收看,希望大家能三连!

最后认识一下,我是爱编程的喷火龙廖,我们有缘再见!

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

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

相关文章

手写分布式存储系统v0.3版本

引言 承接 手写分布式存储系统v0.2版本 &#xff0c;今天开始新的迭代开发。主要实现 服务发现功能 一、什么是服务发现 由于咱们的服务是分布式的&#xff0c;那从服务管理的角度来看肯定是要有一个机制来知道具体都有哪些实例可以提供服务。举个例子就是&#xff0c;张三家…

DevOps落地笔记-07|案例分析:如何有效管理第三方组件

上一讲主要介绍了如何通过代码预检查的方式提高入库代码的质量&#xff0c;将代码检查尽可能前置&#xff0c;降低修复问题的成本&#xff0c;从而提高交付软件的质量。除了代码本身的问题&#xff0c;依赖组件也是经常困扰开发者的一个问题。比如&#xff0c;依赖组件的某个版…

认识Tomcat (一)

认识Tomcat &#xff08;一&#xff09; 一、服务器 1.1 服务器简介 ​ 硬件服务器的构成与一般的PC比较相似&#xff0c;但是服务器在稳定性、安全性、性能等方面都要求更高&#xff0c;因为CPU、芯片组、内存、磁盘系统、网络等硬件和普通PC有所不同。 ​ 软件服务器&…

深度学习(生成式模型)—— Consistency Models

文章目录 前言预备知识&#xff1a;SDE与ODEMethod实验结果 前言 Diffusion model需要多次推断才能生成最终的图像&#xff0c;这将耗费大量的计算资源。前几篇博客我们已经介绍了加速Diffusion model生成图像速率的DDIM和Stable Diffusion&#xff0c;本节将介绍最近大火的Co…

【Matplotlib】figure方法 你真的会了吗!?

&#x1f388;个人主页&#xff1a;甜美的江 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;matplotlib &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

解放双手!ChatGPT助力编写JAVA框架!

摘要 本文介绍了使用 ChatGPT逐步创建 一个简单的Java框架&#xff0c;包括构思、交流、深入优化、逐步完善和性能测试等步骤。 亲爱的Javaer们&#xff0c;在平时编码的过程中&#xff0c;你是否曾想过编写一个Java框架去为开发提效&#xff1f;但是要么编写框架时感觉无从下…

Tauri:相比Electron,还有很长路要走的。

一、Tauri是什么 Tauri是一个开源的框架&#xff0c;用于构建跨平台的桌面应用程序。它允许开发者使用Web技术&#xff08;如HTML、CSS和JavaScript&#xff09;来构建高性能的本地应用程序&#xff0c;同时提供了访问底层操作系统功能的能力。 Tauri的设计目标是提供一种简单…

第97讲:MHA高可用集群模拟主库故障以及修复过程

文章目录 1.分析主库故障后哪一个从库会切换为主库2.模拟主库故障观察剩余从库的状态2.1.模拟主库故障2.3.当前主从架构 3.修复故障的主库3.1.修复主库3.2.当前主从架构3.3.恢复MHA 1.分析主库故障后哪一个从库会切换为主库 在模拟MHA高可用集群主库故障之前&#xff0c;我们先…

【JavaSE篇】——抽象类和接口

目录 &#x1f393;抽象类 &#x1f388;抽象类语法 &#x1f388;抽象类特性 &#x1f388;抽象类的作用 &#x1f393;接口 &#x1f388;语法规则 &#x1f388;接口特性 &#x1f388;接口使用(实现USB接口&#xff09; &#x1f388;实现多个接口 &#x1f388;…

力扣刷题之旅:进阶篇(一)

力扣&#xff08;LeetCode&#xff09;是一个在线编程平台&#xff0c;主要用于帮助程序员提升算法和数据结构方面的能力。以下是一些力扣上的入门题目&#xff0c;以及它们的解题代码。 --点击进入刷题地址 题目1&#xff1a;三数之和 题目描述&#xff1a; 给定一个包含n个…

代码随想录算法训练营第41天 | 343.整数拆分 + 96.不同的二叉搜索树

今日任务 343. 整数拆分 96.不同的二叉搜索树 343.整数拆分 - Medium 题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 给定一个正整数 n &#xff0c;将其拆分为 k 个 正整数 的和&#xff08; k > 2 &#xff09;&#xff0…

springboot+vue实现excel导出

后端 导入pom依赖 <dependency>x<groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter</artifactId><version>4.2.0</version> </dependency> Entity实体类 这里以User为例&#xff0c;可按照自己实际…

vulhub中AppWeb认证绕过漏洞(CVE-2018-8715)

AppWeb是Embedthis Software LLC公司负责开发维护的一个基于GPL开源协议的嵌入式Web Server。他使用C/C来编写&#xff0c;能够运行在几乎先进所有流行的操作系统上。当然他最主要的应用场景还是为嵌入式设备提供Web Application容器。 AppWeb可以进行认证配置&#xff0c;其认…

【CSS】css如何实现字体大小小于12px?

【CSS】css如何实现字体大小小于12px? 问题解决方案transform: scale(0.5)&#xff08;常用&#xff09;SVG 矢量图设置text 问题 文字需要显示为12px&#xff0c;但是小于12px的&#xff0c;浏览器是显示不来的 解决方案 transform: scale(0.5)&#xff08;常用&#xff0…

树莓派-Ubuntu22.04

树莓派 1 安装Ubuntu系统2 ssh登录3 配置3.1 安装软件3.2 换源3.3 安装桌面3.4 开机脚本 1 安装Ubuntu系统 通过制作sdk&#xff0c;使系统在sdk中运行&#xff1a; 下载制作软件&#xff1a;https://www.raspberrypi.com/software/ 下载Ubuntu镜像&#xff1a;https://cn.ub…

【Day40】代码随想录之动态规划_343. 整数拆分_96.不同的二叉搜索树

文章目录 动态规划理论基础动规五部曲&#xff1a;出现结果不正确&#xff1a; 343. 整数拆分96.不同的二叉搜索树 动态规划理论基础 动规五部曲&#xff1a; 确定dp数组 下标及dp[i] 的含义。递推公式&#xff1a;比如斐波那契数列 dp[i] dp[i-1] dp[i-2]。初始化dp数组。…

基于Springboot开发的JavaWeb作业查重系统[附源码]

基于Springboot开发的JavaWeb作业查重系统[附源码] &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系统 &a…

zlib交叉编译(rv1126)

目录 1.下载 2.解压 3.配置 4.编译 1.下载 1)下载地址 zlib Home Site 2)下载tar.gz版本 下载该版本。 2.解压 1)解压到某个文件夹

探索设计模式的魅力:从单一继承到组合模式-软件设计的演变与未来

设计模式专栏&#xff1a;http://t.csdnimg.cn/nolNS 在面对层次结构和树状数据结构的软件设计任务时&#xff0c;我们如何优雅地处理单个对象与组合对象的一致性问题&#xff1f;组合模式&#xff08;Composite Pattern&#xff09;为此提供了一种简洁高效的解决方案。通过本…

简单的JavaScript去下载转换为Base64的PDF文件

新建一个文件&#xff0c;内容填写如下&#xff0c;然后保存为 .html 类型的文件 再用浏览器打开&#xff0c;就会是下面这样子&#xff1a; 图一红色textarea里面&#xff0c;可以将PDF文件转换成BASE64位后的内容贴进去&#xff0c;点击下载时&#xff0c;就可以直接下载成PD…