C++基础算法:高精度

server/2025/3/11 9:55:17/

在这里插入图片描述

文章目录

  • 1.[P1601 A+B Problem(高精)](https://www.luogu.com.cn/problem/P1601)
    • 题目解析:
    • 算法原理:
    • 代码实现
  • 2.[P2142 高精度减法 - 洛谷](https://www.luogu.com.cn/problem/P2142)
  • 3.[P1303 A*B Problem - 洛谷](https://www.luogu.com.cn/problem/P1303)
  • 4.[P1480 A/B Problem - 洛谷](https://www.luogu.com.cn/problem/P1480)

1.P1601 A+B Problem(高精)

1741143771642

题目解析:

1741144972468

由于是高精度的计算所以无法直接相加,需要先用字符串将数字存起来,后根据字符数字减去字符0可以转化为int类型来进行模拟列竖式进行加法

算法原理:

我们为了方便进行模拟我们在列竖式时的过程我们可以将原本的数反过来放入数组:

1741142580020

对应关系如上,写成代码:

int main()
{string s1,s2; cin>>s1>>s2;for(int i = 0;i<s1.size();i++) a[s1.size()-1-i] = s1[i] - '0';for(int i = 0;i<s2.size();i++) b[s2.size()-1-i] = s2[i] - '0';
}

再将主要逻辑写出来:

int main()
{string s1,s2; cin>>s1>>s2;la = s1.size(); lb = s2.size();lc = max(la,lb); for(int i = 0;i<s1.size();i++) a[s1.size()-1-i] = s1[i] - '0';for(int i = 0;i<s2.size();i++) b[s2.size()-1-i] = s2[i] - '0';add();for(int i = lc - 1;i>=0;i--) cout<<c[i]; return 0;
}

这里lc为相加后的长度,先直接取为两数的最大值,后续再根据结果进行判断:如果最前面不为0就lc++

模拟列竖式:

可以将进位直接放入到数组的前一位,直接相加后,进行进位和留余操作即可

最后判断最前方是否有数,如果有就将lc向前一位

代码如下:

#include <iostream>
using namespace std;
const int N = 1e6+10;
int a[N],b[N],c[N];
int la,lb,lc;void add()
{for(int i = 0;i<lc;i++){c[i] += a[i]+b[i];//一定是+=将进行的数加上c[i+1] = c[i]/10; //进位 c[i] %= 10; 	  //留余 }//处理前置数if(c[lc]) lc++; 
}

代码实现

#include <iostream>
using namespace std;
const int N = 1e6+10;
int a[N],b[N],c[N];
int la,lb,lc;void add()
{for(int i = 0;i<lc;i++){c[i] += a[i]+b[i];c[i+1] = c[i]/10;//进位 c[i] %= 10; 	 //留余 }//处理前置数if(c[lc]) lc++; 
}
int main()
{string s1,s2; cin>>s1>>s2;la = s1.size(); lb = s2.size();lc = max(la,lb); for(int i = 0;i<s1.size();i++) a[s1.size()-1-i] = s1[i] - '0';for(int i = 0;i<s2.size();i++) b[s2.size()-1-i] = s2[i] - '0';add();for(int i = lc - 1;i>=0;i--) cout<<c[i]; return 0;
}

2.P2142 高精度减法 - 洛谷

image-20250310113018847

算法原理

和之前一样需要先将字符串导致存放到数组中方便运算,但是减法和加法 有一个本质的区别就是:

减法需要用大数字减去小数字这样我们可以直接进行比较,然后交换两者数据,一旦交换直接在前面输出一个-

即可直接进行大数减小数

  1. 交换数据

    • 根据字符串长度来判断
    • 字符串长度一样可以根据字符串直接进行比较
    bool my_swap(string &s1,string &s2)
    {if(s1.size()!=s2.size()) return s1.size()<s2.size();else return s1<s2;
    }int main()
    {string s1,s2; cin>>s1>>s2;if(my_swap(s1,s2)){swap(s1,s2);cout<<'-';}
    }
    
  2. 和加法一样将字符串倒置方便后续计算

    #include <iostream>
    using namespace std;const int N = 1e6+10;
    int la,lb,lc;
    int a[N],b[N],c[N];
    int main()
    {string s1,s2; cin>>s1>>s2;if(my_swap(s1,s2)){swap(s1,s2);cout<<'-';}la = s1.size();lb = s2.size();lc = max(la,lb);for(int i = 0;i<la;i++) a[i] = s1[la-1-i] - '0';for(int i = 0;i<lb;i++) b[i] = s2[lb-1-i] - '0';
    }
    
  3. 减法的逻辑

    • 直接进行减法
    • 如果不够进行借数
    • 如果前面的数字相减为0,就需要处理前置0
    void sub()
    {for(int i = 0;i<lc;i++){c[i] += a[i] - b[i];//直接进行减法if(c[i]<0)//如果不够进行借数{c[i] += 10;c[i+1] -= 1;}}while(c[lc-1]==0&&lc>1) lc--;//前置0
    }
    

    这里要注意lc > 1不要访问越界

    image-20250310135711876

代码实现

#include <iostream>
using namespace std;const int N = 1e6+10;
int la,lb,lc;
int a[N],b[N],c[N];bool my_swap(string &s1,string &s2)
{if(s1.size()!=s2.size()) return s1.size()<s2.size();else return s1<s2;
}void sub()
{for(int i = 0;i<lc;i++){c[i] += a[i] - b[i];if(c[i]<0){c[i] += 10;c[i+1] -= 1;}}while(c[lc-1]==0&&lc>1) lc--;
}
int main()
{string s1,s2; cin>>s1>>s2;if(my_swap(s1,s2)){swap(s1,s2);cout<<'-';}la = s1.size();lb = s2.size();lc = max(la,lb);for(int i = 0;i<la;i++) a[i] = s1[la-1-i] - '0';for(int i = 0;i<lb;i++) b[i] = s2[lb-1-i] - '0';sub();for(int i = lc-1;i>=0;i--) cout<<c[i];return 0;
}

3.P1303 A*B Problem - 洛谷

image-20250310135827126

算法原理

  1. 乘法逻辑

    如果我们直接进行进位就会让这道题变得复杂,但是如果我们现将要加的数字先直接加到数组中,接着在按照加法的逻辑进行相加就会让这道题简单不少

    • 找到相加的规律(c[i+j] += a[i]*b[j])

      image-20250310142702184

    • 进行进位

    • 处理前置0

    void mul()
    {for(int i = 0;i<la;i++){for(int j = 0;j<lb;j++){c[i+j] += a[i]*b[j];}}for(int i = 0;i<lc;i++){c[i+1] += c[i] / 10;c[i] %= 10;}while(lc>1&&c[lc-1]==0) lc--;
    }
    
  2. 再将主函数进行补齐

    int main()
    {string s1,s2; cin>>s1>>s2;la = s1.size();lb = s2.size();lc = la+lb;for(int i = 0;i<la;i++) a[i] = s1[la-i-1] - '0';for(int i = 0;i<lb;i++) b[i] = s2[lb-i-1] - '0';mul();for(int i = lc-1;i>=0;i--) cout<<c[i];return 0;
    }
    

代码实现

#include <iostream>
using namespace std;const int N = 1e6+10;
int a[N],b[N],c[N];
int la,lb,lc;void mul()
{for(int i = 0;i<la;i++){for(int j = 0;j<lb;j++){c[i+j] += a[i]*b[j];}}for(int i = 0;i<lc;i++){c[i+1] += c[i] / 10;c[i] %= 10;}while(lc>1&&c[lc-1]==0) lc--;
}
int main()
{string s1,s2; cin>>s1>>s2;la = s1.size();lb = s2.size();lc = la+lb;for(int i = 0;i<la;i++) a[i] = s1[la-i-1] - '0';for(int i = 0;i<lb;i++) b[i] = s2[lb-i-1] - '0';mul();for(int i = lc-1;i>=0;i--) cout<<c[i];return 0;
}

4.P1480 A/B Problem - 洛谷

image-20250310145407893

算法原理

这里不是两个数都是高精度,仅仅只有被除数是高精度,而除数为longlong类型即可,这道题需要注意int类型是否越界

  1. 除法原理

    • 我们需要创建一个变量来保存上一位的余数,而对于下一位的我们需要将上一位的余数*10+下一位的原本的数字再去执行除法逻辑即可
    void sub()
    {long long ret = 0;for(int i = la-1;i>=0;i--){a[i] += ret*10;c[i] = a[i] / n;ret = a[i]%n;}while(lc>1&&c[lc-1]==0) lc--;
    }
    
  2. 其他的部分与上面差不多(要注意int的范围,不要数据让数据丢失)

    #include <iostream>
    using namespace std;
    const int N = 1e6+10;
    long long a[N],c[N];
    int la,lc;
    long long n;int main()
    {string s; cin>>s;cin>>n;la = s.size();lc = la;for(int i = 0;i<la;i++) a[i] = s[la-i-1] - '0';sub();for(int i = lc-1;i>=0;i--) cout<<c[i];return 0;
    }
    

代码实现

#include <iostream>
using namespace std;
const int N = 1e6+10;
long long a[N],c[N];
int la,lc;
long long n; void sub()
{long long ret = 0;for(int i = la-1;i>=0;i--){a[i] += ret*10;c[i] = a[i] / n;ret = a[i]%n;}while(lc>1&&c[lc-1]==0) lc--;
}
int main()
{string s; cin>>s;cin>>n;la = s.size();lc = la;for(int i = 0;i<la;i++) a[i] = s[la-i-1] - '0';sub();for(int i = lc-1;i>=0;i--) cout<<c[i];return 0;
}

http://www.ppmy.cn/server/174148.html

相关文章

基于磁数据的伤痕、生锈、断丝分类训练平台搭建规划

基于磁数据的伤痕、生锈、断丝分类训练平台搭建规划 一、项目概述 本项目旨在搭建一个训练平台&#xff0c;通过磁数据以及震荡变化来识别物体表面的伤痕、生锈和断丝情况。平台将涵盖数据标记、算法设计、模型调优以及模型交付等一系列功能。 二、平台搭建步骤 &#xff08;一…

机器学习模型-从线性回归到神经网络

在当今的数据驱动世界中&#xff0c;机器学习模型是许多应用程序的核心。无论是推荐系统、图像识别&#xff0c;还是自动驾驶汽车&#xff0c;机器学习技术都在背后发挥着重要作用。在这篇文章中&#xff0c;我们将探索几种基础的机器学习模型&#xff0c;并了解它们的基本原理…

MySQL基本建表操作

一、创建数据库db_ck和表db_hero 1、创建表 mysql> create database db_ck default charset"utf8mb4";mysql> create table if not exists db_hero(-> id int not null,-> name varchar(100) not null,-> nickname varchar(100),-> age int,->…

从0到1,带你开启TypeScript的奇妙之旅

目录 一、TypeScript 是什么? 二、为什么要学习 TypeScript? 三、快速上手:环境搭建与 Hello World (一)安装 TypeScript (二)创建第一个 TypeScript 文件 (三)编译 TypeScript 文件 (四)运行编译后的 JavaScript 文件 四、深入 TypeScript 核心语法 (一)…

开源安全测试工具 | 网络安全工具列表

自动化渗透测试 • AttackSurfaceMapper (https://github.com/superhedgy/AttackSurfaceMapper) - 自动化渗透测试工具, 使用手册/测试流程 (https://www.uedbox.com/post/59110/)。 • vajra (https://github.com/r3curs1v3-pr0xy/vajra) - 自动化渗透测试. • Savior (https…

cursor | 30分钟做一个个人网站(可供外网访问~)

目录 0. 安装与配置 Cursor 一、Cursor 代码生成阶段&#xff08;核心阶段&#xff09; 二、阿里云服务配置&#xff08;关键配置项&#xff09; 三、高级功能集成 四、调试与监控 之前看到了不少关于 cursor 0 代码搭建的宣传&#xff0c;博主今天上美育课&#xff0c;突…

华为OD机试-箱子之字形摆放(Java 2024 E卷 100分)

题目描述 我们需要将一批箱子(形式为字符串 str)按从上到下的 Z 字形顺序摆放在宽度为 n 的空地上,并输出箱子的摆放位置。 示例 输入:ABCDEFG 3 输出: AFG BE CD解题思路 我们可以通过模拟 Z 字形的过程来解决这个问题。具体步骤如下: 创建一个列表(或数组)来存…

mac安装nvm=>node=>nrm

下载并安装 NVM 运行以下命令下载并安装 NVM&#xff1a; curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash 配置环境变量 vim ~/.zshrc 按 i 将如下代码复制进去&#xff0c;controlc &#xff0c;再按 :wq完成编辑 export NVM_DIR…