基础算法

来源:互联网 发布:双机热备 数据库 编辑:程序博客网 时间:2024/06/01 13:57

我们今天来聊聊高精度。
顾名思义,高精度就指精度很高
那么精度很高又指什么呢?
我们知道int(整型)的表示范围是 231~2311
longlong(长整型)的范围是 263 ~ 2631
那么我们就可以认为长整型精度较高,也可以说是表示范围更大
那么高精度有什么用处呢?
我们接下来看一道例题。

A+B Problem

Description

读入两个整数a,b,输出a+b

Input

两个整数a,b(0a,b10500

Output

一个整数a+b

Sample Input

1 2

Sample Output

3

分析

大致地看一下这题,可能发现这题其实并没有什么不对,只要读入输出即可
如果你抱着这样的心态交代码,那么迎接你的将会是WA,甚至爆零
这是为什么呢?且听下回分解
请看数据范围!
没错,不论你用长整型,或者是无符号长整形,甚至是int128,那都是存不下的
这就是为什么我们需要高精度
接下来我们讲高精度的原理。

高精度加法

我们先分析一下数的构成
仔细一看,数是由个位、十位、百位等构成的
那么我们就可以说一个数是由多个数位构成的
我们不妨将每个数位都分开来存在一个数组里,以此加大数的表示范围
问题就好解决了
数组开多大,数的表示范围就有几位(比如上面那题我们可以开a[505]
我个人习惯使用如下的结构体:

struct hugeint{    int l,n[505];//l代表数的长度,n用来存储数的每一位}a;

注意,这里的a[1]代表个位,a[2]代表十位,以此类推
接下来我们只要模仿竖式的过程,就可以轻松地进行高精度加法了
还记得竖式么?

    5 6    3 3——————————    8 9

于是乎,代码呼之欲出

非压位优化高精度加法模板.cpphugeint Plus(hugeint a,hugeint b)//作为加数的a,b{    hugeint ans;    memset(ans.n,0,sizeof(ans.n));    ans.l=0;    for(int i=1;i<=max(a.l,b.l);i++)//从第一位开始循环    {        ans.n[i]+=a.n[i]+b.n[i];//加上        if(ans.n[i]>=10)//进位处理        {            ans.n[i+1]+=ans.n[i]/10;            ans.n[i]%=10;            if(i==max(a.l,b.l)) ans.l++;//如果最后一位要进位,长度+1        }        ans.l++;//每一位长度+1    }    return ans;}

输出模板:

void Print(hugeint a){    for(int i=a.l;i>=1;i--) printf("%d",a.n[i]);}

小结

高精度是OI中非常重要的元素,本人在这里只列出了加法,大家可以自行研究一下减法、乘法和除法,实在理解不了背下来也是可行的方法。

原创 By Venus
写的不好大佬轻喷

原创粉丝点击