【马蹄集】第二十四周——高精度计算专题

高精度计算专题



目录

  • MT2191 整数大小比较
  • MT2192 A+B problem
  • MT2193 A-B problem
  • MT2194 大斐列
  • MT2195 升级版斐波那契数列
  • MT2196 2的N次幂




MT2191 整数大小比较

难度:黄金    时间限制:1秒    占用内存:128M
题目描述

给出两个正整数,判断它们的大小。

格式

输入格式:两个正整数。
输出格式:若前者大,输出 >;若后者大,输出 <;若一样大,输出 =

样例 1

输入:1412894619244619891 23762842222

输出:>

备注

保证所有数在 2 100 2^{100} 2100 以内。


相关知识点:高精度计算


题解


虽然这道题是比较数字的大小,但实际上我们不用关心其数字的取值范围(可以从字符串对象的角度出发进行比较)。对于任意两个正整数,它们之间的大小关系可根据以下两步进行比较:

  1. 数字长度。对于正整数而言,显然长度越长的数更大。
  2. 若长度相等,则从数的最高位到最低位依次比较大小,在某位上具有更大数字的数更大。

若 1、2 之后未能找到更大的数,则说明这两个数的取值相同。

基于此,可直接写出求解该题的完整代码(已 AC):

/*MT2191 整数大小比较 
*/
#include<bits/stdc++.h> 
using namespace std;// 比较两个大数的大小 
int compare(string stra, string strb)
{// 根据长度判断大小关系 int lenA = stra.length();int lenB = strb.length();if(lenA > lenB) return 1;if(lenA < lenB) return -1;// 长度相等需要进一步判断for(int i=0; i<lenA; i++){if(stra[i] - strb[i] > 0) return 1;if(stra[i] - strb[i] < 0) return -1;}// 或者直接比较字符串大小// if(stra > strb) return 1;// else if(stra < strb) return -1;// else return return 0;
}// 打印结果
void printResult(int result)
{if(result > 0) cout<<">"<<endl;else if(result < 0) cout<<"<"<<endl;else cout<<"="<<endl;
}int main( )
{// 获取输入 string stra, strb;cin>>stra>>strb;// 比较两个大数的大小int result = compare(stra, strb);// 输出比较结果printResult(result);return 0;
} 



MT2192 A+B problem

难度:黄金    时间限制:1秒    占用内存:128M
题目描述

计算 A + B ( 1 ≤ A , B ≤ 10 10000 ) A+B(1\le A,B\le{10}^{10000}) A+B(1A,B1010000)

格式

输入格式:两行每行一个整数 A , B A,B A,B
输出格式:一个整数 A + B A+B A+B

样例 1

输入:

1
1

输出:

2


相关知识点: 高精度计算


题解


这道题考察的是大数运算(加法)。关于如何实现大数加法运算的分析请见博客 【算法与数据结构】——大数运算 。下面给出多位数加法的执行流程:

在这里插入图片描述

多位数加法的过程涉及到对各个位的加法运算,因此在处理大数的加法运算时,通常会用一个 int 型数组来存储大数在各个位上的值。例如,数:122333444455555666666,可通过一个足够长的数组 a r y [ ] ary[\ ] ary[ ] ,使 a r y [ 0 ] = 1 , a r y [ 1 ] = 2 , a r y [ 3 ] = 2 , … , a r y [ 20 ] = 6 ary\left[0\right]=1,ary\left[1\right]=2,ary\left[3\right]=2,\ldots,ary\left[20\right]=6 ary[0]=1,ary[1]=2,ary[3]=2,,ary[20]=6 进行存储。采取数位与索引大小相对应的存储方式(即数的低位对应较小的索引,高位对应较大的索引),是为了便于大数在执行加法运算时的进位可直接在数组中向后拓展。接下来,就能按照以上思路扫描数组并对各个位进行加法运算。最后,单独用一层循环处理进位即可。

下面直接给出求解本题的完整代码(已 AC):

/*MT2192 A+B problem 
*/
#include<bits/stdc++.h> 
using namespace std;const int N = 1e4+5;
int numa[N], numb[N];// 计算两个大数之和(输入为字符串) 
void getSum(string stra, string strb)
{// 赋初值memset(numa, 0, sizeof(numa));memset(numb, 0, sizeof(numb));int tmp = 0;// 将两个字符串保存至 int 型数组中(注意逆序) for(int i=stra.length()-1; i>=0; i--)numa[tmp++] = stra[i] - '0';tmp = 0;for(int i=strb.length()-1; i>=0; i--)numb[tmp++] = strb[i] - '0';// 将数组中的每个数按位进行加法运算for(int i=0;i<N;i++)numa[i] += numb[i];// 对存放加法结果的数组执行进位处理for(int i=0; i<N; i++){numa[i+1] += numa[i] / 10;numa[i] %= 10;}
}// 输出大数加法后的结果 
void printBigData()
{// 从最高位向后扫描,直到第 1 个非 0 数字出现 int p = N-1;while(numa[p] == 0) p--;while(p >= 0) cout<<numa[p--];cout<<"\n";
} int main( )
{// 获取输入 string stra, strb;cin>>stra>>strb;// 对两个大数进行加法运算 getSum(stra, strb);// 输出和printBigData();return 0;
} 


MT2193 A-B problem

难度:黄金    时间限制:1秒    占用内存:128M
题目描述

计算 A − B ( 1 ≤ B ≤ A ≤ 10 10000 ) A-B(1\le B\le A\le{10}^{10000}) AB(1BA1010000)

格式

输入格式:两行每行一个整数 A , B A,B A,B
输出格式:一个整数 A − B A-B AB

样例 1

输入:

2
1

输出:

1

相关知识点: 高精度计算


题解


这道题考察的是大数运算(减法)。关于如何实现大数减法运算的分析请见博客 【算法与数据结构】——大数运算 。下面给出多位数减法的执行流程:

在这里插入图片描述

多位数减法需要用到 int 型数组来存储大数在各个位上的值,其存储规则和大数加法一致(即低位对应较小的索引,高位对应较大的索引)。接下来,只需要扫描数组,在每个位上按照以上思路进行减法运算即可得到大数减法的结果。

下面直接给出求解本题的完整代码(已 AC):

/*MT2193 A-B problem 
*/
#include<bits/stdc++.h> 
using namespace std;const int N = 1e4+5;
int numa[N], numb[N];// 计算两个大数之差(输入为字符串) 
void getSub(string stra, string strb)
{// 赋初值memset(numa, 0, sizeof(numa));memset(numb, 0, sizeof(numb));int tmp = 0;// 将两个字符串保存至 int 型数组中(注意逆序) for(int i=stra.length()-1; i>=0; i--)numa[tmp++] = stra[i] - '0';tmp = 0;for(int i=strb.length()-1; i>=0; i--)numb[tmp++] = strb[i] - '0';// 将数组中的每个数按位进行减法运算for(int i=0;i<N;i++){numa[i] -= numb[i];if(numa[i] < 0){// 借位 numa[i+1]--; numa[i] += 10;}}
}// 输出大数减法后的结果 
void printBigData()
{// 从最高位向后扫描,直到第 1 个非 0 数字出现 int p = N-1;while(numa[p] == 0) p--;while(p > -1) cout<<numa[p--];cout<<"\n";
} int main( )
{// 获取输入 string stra, strb;cin>>stra>>strb;// 对两个大数进行减法运算 getSub(stra, strb);// 输出和printBigData();return 0;
} 


MT2194 大斐列

难度:黄金    时间限制:1秒    占用内存:128M
题目描述

计算斐波那契数列第 n n n 项。
斐波那契数列定义为: F [ 1 ] = 1 , F [ 2 ] = 1 F[1] = 1,F[2] = 1 F[1]=1F[2]=1,递推关系为: F [ N ] = F [ N − 1 ] + F [ N − 2 ] F[N] = F[N-1] + F[N-2] F[N]=F[N1]+F[N2]。即: 1 、 1 、 2 、 3 、 5 、 8 、 13 、 21 、 34 、 … … 1、1、2、3、5、8、13、21、34、…… 112358132134……

格式

输入格式:一个整数 n n n
输出格式:一个整数 F [ n ] F[n] F[n]

样例 1

输入:6

输出:8

备注

对于 30% 的数据: 3 ≤ n ≤ 20 3≤n≤20 3n20
对于 100% 的数据: 3 ≤ n ≤ 5000 3≤n≤5000 3n5000


相关知识点:高精度计算


题解


这道题实际上就是求斐波那契数列:即通过迭代公式 F [ N ] = F [ N − 1 ] + F [ N − 2 ] F[N] = F[N-1] + F[N-2] F[N]=F[N1]+F[N2],不断获取下一个值。但是斐波那契数列的增长速度非常快,通过编写 Python 代码可知(代码如下),斐波那契数列的第 5000 个数的长度达到了 1045。因此这道题是一道妥妥的大数加法问题。

# 求斐波那契的第 5000 项
ary = [1,1]
for i in range(2,5000):ary.append(ary[i-1]+ary[i-2])
print(ary[4999])
print(len(str(ary[4999])))

Python 求解斐波那契数列

所以这里依然需要用到大数加法。具体的实现方式和前面类似,在此就不赘述。

下面给出基于以上思路写出的完整代码(已 AC):

/*MT2194 大斐列 通过 python 算出最后数字(即第 5000 项)的长度为 1045
*/
#include<bits/stdc++.h> 
using namespace std;const int N = 1100;
int numa[N], numb[N], numc[N];// 计算斐波那契数列
void getFibonacci(int n)
{// 赋初值memset(numa, 0, sizeof(numa));memset(numb, 0, sizeof(numb));memset(numc, 0, sizeof(numc));numa[0] = numb[0] = 1;n -= 2;// 递推求解斐波那契数列并统计前缀和 while(n--){// 将数组中的每个数按位进行加法运算 for(int i=0;i<N;i++)numc[i] = numa[i] + numb[i];// 对存放加法结果的数组执行进位处理for(int i=0; i<N; i++){numc[i+1] += numc[i] / 10;numc[i] %= 10;}// 将数组进行前向赋值(从而实现递推)memcpy(numa, numb, sizeof(numb));memcpy(numb, numc, sizeof(numc));}
}// 输出大数加法后的结果 
void printBigData()
{// 从最高位向后扫描,直到第 1 个非 0 数字出现 int p = N-1;while(numc[p] == 0) p--;while(p > -1) cout<<numc[p--];cout<<"\n";
} int main( )
{// 获取输入 int n;cin>>n;// 求出斐波那契数列 getFibonacci(n);// 输出指定项 printBigData();return 0;
} 


MT2195 升级版斐波那契数列

难度:黄金    时间限制:1秒    占用内存:128M
题目描述

我们都知道斐波那契数列一项是前两项的和,现在我们规定一个升级版斐波那契数列,其一项为前三项的和,要求算其前 n n n 项的和。即,定义: F [ 1 ] = 1 , F [ 2 ] = 1 , F [ 3 ] = 1 F[1] = 1,F[2] = 1,F[3] = 1 F[1]=1F[2]=1F[3]=1,递推关系为: F [ N ] = F [ N − 1 ] + F [ N − 2 ] + F [ N − 3 ] F[N] = F[N-1] + F[N-2] + F[N-3] F[N]=F[N1]+F[N2]+F[N3]

格式

输入格式:一个整数 n n n
输出格式:前 n n n 项的和。

样例 1

输入:4

输出:6

备注

其中: 4 ≤ n ≤ 1000 4\le n \le 1000 4n1000


相关知识点:高精度计算


题解


这道题依然考察了大数加法,和前面一题类似,下面直接给出求解本题的完整代码(已 AC):

/*MT2195 升级版斐波那契数列 通过 python 算出最后数字(即第 1000 项)的长度为 265,整个数列的数字之和长度为 265
*/
#include<bits/stdc++.h> 
using namespace std;const int N = 300;
int numa[N], numb[N], numc[N], numd[N], preSum[N];// 计算斐波那契数列
void getFibonacci(int n)
{// 赋初值memset(numa, 0, sizeof(numa));memset(numb, 0, sizeof(numb));memset(numc, 0, sizeof(numc));memset(numd, 0, sizeof(numd));memset(preSum, 0, sizeof(preSum));numa[0] = numb[0] = numc[0] = 1;preSum[0]  = 3;n -= 3;// 递推求解斐波那契数列并统计前缀和 while(n--){// 将数组中的每个数按位进行加法运算 for(int i=0;i<N;i++)numd[i] = numa[i] + numb[i] + numc[i];// 对存放加法结果的数组执行进位处理for(int i=0; i<N; i++){numd[i+1] += numd[i] / 10;numd[i] %= 10;}// 将当前项累加至前缀和数组中for(int i=0;i<N;i++)preSum[i] += numd[i];for(int i=0; i<N; i++){preSum[i+1] += preSum[i] / 10;preSum[i] %= 10;}// 将数组进行前向赋值memcpy(numa, numb, sizeof(numb));memcpy(numb, numc, sizeof(numc));memcpy(numc, numd, sizeof(numd));}
}// 输出大数加法后的结果 
void printBigData()
{// 从最高位向后扫描,直到第 1 个非 0 数字出现 int p = N-1;while(preSum[p] == 0) p--;while(p > -1) cout<<preSum[p--];cout<<"\n";
} int main( )
{// 获取输入 int n;cin>>n;// 求出斐波那契数列 getFibonacci(n);// 输出前缀和 printBigData();return 0;
} 


MT2196 2的N次幂

难度:黄金    时间限制:1秒    占用内存:128M
题目描述

任意给定一个正整数 N ( N ≤ 100 ) N(N\le100) N(N100) ,计算 2 的 N N N 次方的值。

格式

输入格式:一个正整数 N N N
输出格式:输出 2 N 2^N 2N 的值。

样例 1

输入:5

输出:32


相关知识点:高精度计算


题解


2 n 2^n 2n n n n 取 100 时,是一个长度为 31 的大数,因此也是一道高精度题。与前面不同的是,这道题要求的是乘幂运算。但实际上,数的乘幂运算就等于进行 “幂” 次乘法运算(叠乘),乘数为底数。所以求解该题的关键实际是基于乘法运算的高精度计算问题,关于如何实现大数乘法运算的分析请见博客 【算法与数据结构】——大数运算 。

这里选用的数据结构依然是 int 型数组,其存储规则和大数加法一致(即低位对应较小的索引,高位对应较大的索引)。不过在算法一开始,需要将该数组的最低位置为底数(即 2)。接下来,定义一重循环(循环次数为 n − 1 n-1 n1),每遍都执行以下两步:

  • 将存放大数的数组中的每一位都乘以底数;
  • 遍历整个数组执行进位。

算法结束时,即得到了大数乘幂运算的结果。下面给出基于以上思路得到的完整代码:

/*MT2196 2的N次幂  
*/
#include<bits/stdc++.h> 
using namespace std;// 题目给的数据范围保证了结果不超过 32 位 
const int N = 32;
int num[N];// 高精度乘幂运算
void getHighPrecision(int base, int power)
{// 初始化存放运算结果的数组 memset(num, 0, sizeof(num));// 给数组赋初值 num[0] = base;// 执行乘幂运算 while(--power){// 将数组中的每个数进行乘法运算 for(int i=0; i<N; i++)num[i] *= base;// 对数组执行进位处理for(int i=0; i<N; i++){num[i+1] += num[i] / 10;num[i] %= 10;}}
}// 输出高精度运算后的大数
void printBigData()
{// 从最高位向后扫描,直到第 1 个非 0 数字出现 int p = N-1;while(num[p] == 0) p--;while(p > -1) cout<<num[p--];cout<<"\n";
} int main( )
{// 获取输入 int n;cin>>n;// 执行乘幂的高精度运算getHighPrecision(2, n);// 输出 printBigData();return 0;
} 

END


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

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

相关文章

Python中if __name__ == ‘__main__‘:的作用和原理

if name ‘main’:的作用 一个python文件通常有两种使用方法&#xff0c; 第一是作为脚本直接执行&#xff0c;第二是 import 到其他的 python 脚本中被调用&#xff08;模块重用&#xff09;执行。 举例说明如下&#xff1a; 在本文件中&#xff0c;name 是main 在被impor…

Java for循环每次都通过list.size()和 string.length()获取大小性能

有人说在for循环之前用一个局部变量先获取到list.size()、str.length()&#xff0c;然后在for循环的判断条件里通过这个局部变量替换list.size()、str.length()会节省数据计算的时间。事实真的是这样吗&#xff1f;下面就为大家解答这个问题。 说明&#xff1a;此文章针对Andro…

10 mysql tiny/small/medium/big int 的数据存储

前言 这里主要是 由于之前的一个 datetime 存储的时间 导致的问题的衍生出来的探究 探究的主要内容为 int 类类型的存储, 浮点类类型的存储, char 类类型的存储, blob 类类型的存储, enum/json/set/bit 类类型的存储 本文主要 的相关内容是 int 类类型的相关数据的存储 …

气象站是什么设备?功能是什么?

气象站是一种用于测量和记录气象数据的设备。它通常是由各种传感器及其数据传输设备、固定设备和供电设备组成&#xff0c;可以测量风速、风向、温度、湿度、气压、降水量等气象要素&#xff0c;并将这些数据记录下来&#xff0c;以便进一步分析和研究。 气象站通常设置在广阔…

【U盘】实现U盘清空并重置恢复存储

打开电脑&#xff0c;将U盘插入USB端口&#xff0c;点按快捷键【WinR】&#xff0c;弹出运行对话框&#xff0c;输入命令 diskpart 进入命令提示符窗口 输入指令 list disk 查看现在的硬盘 这里显示的U盘编号是“1”&#xff0c;因此输入select disk “1”&#xff0c;就是选择…

CS420 课程笔记 P3 - 计数系统基础和 Hex, Decimal, Binary 进制

文章目录 IntroductionInspirationWhy base systemsBinary & HexCounting in binaryAdditional resources Introduction 笔记作者 tips&#xff1a;这一节是关于进制的讲解&#xff0c;推荐观看原视频或学会二进制的读者跳过这一篇&#xff01; 本节课将介绍基本的计算机系…

动态规划:路径和子数组问题(C++)

动态规划&#xff1a;路径和子数组问题 路径问题1.不同路径&#xff08;中等&#xff09;2.不同路径II&#xff08;中等&#xff09;3.下降路径最⼩和&#xff08;中等&#xff09;4.地下城游戏&#xff08;困难&#xff09; 子数组问题1.最大子数组和&#xff08;中等&#xf…

无涯教程-JavaScript - MINUTE函数

描述 MINUTE函数返回时间值的分钟。分钟以整数形式给出,范围为0到59。 语法 MINUTE (serial_number)争论 Argument描述Required/OptionalSerial_number 您想要找到的包含分钟的时间。 可以输入时间 作为引号内的文本字符串(如" 6:45 PM") 为十进制数字(如0.7812…

JVM垃圾回收机制和常用算法(简洁版)

垃圾收集 (Garbage Collection,GC) 垃圾收集主要是针对堆和方法区进行。程序计数器、虚拟机栈和本地方法栈这三个区域属于线程私有的&#xff0c;只存在于线程的生命周期内&#xff0c;线程结束之后就会消失&#xff0c;因此不需要对这三个区域进行垃圾回收。 判断一个对象是…

基本介绍——数据挖掘

1.数据挖掘的定义 数据挖掘是采用数学的、统计的、人工智能和神经网络等领域的科学方法&#xff0c;如记忆推理、聚类分析、关联分析、决策树、神经网络、基因算法等技术&#xff0c;从大量数据中挖掘出隐含的、先前未知的、对决策有潜在价值的关系、模式和趋势&#xff0c;并…

基于Springcloud的基础框架,统一gateWay网关鉴权demo,附下载地址

基于Springcloud的基础框架&#xff0c;统一gateWay网关鉴权demo&#xff0c;附下载地址 使用方式&#xff1a; 1、搭建nacos环境&#xff0c;修改对应nacos地址 2、修改mysql地址,导入sql语句 ###框架内容 SpringcloudGatewayJWTNacosFeginmysqlMybatis plus 具体功能 基于…

Swift 周报 第三十六期

文章目录 前言新闻和社区消息称苹果公司和印度财政部官员磋商&#xff0c;扩大在印度的制造产能iPhone 15 Pro 机型新增泰坦灰iPhone 15 全系配 USB-C 苹果拒绝接口和安卓互通 提案正在审查的提案 Swift论坛推荐博文话题讨论关于我们 前言 本期是 Swift 编辑组整理周报的第三十…