写在前面
?? 你曾经是不是有过这样的经历:好不容易用了暴力的方法写出了代码,测试用例也通过了,当心满意足的提交代码后却弹出一个超出”数据范围“的提示,整个人瞬间😱了?我是经常有这样的经历,终于在既懒得优化不会优化又忍受不了的情况下,我发现了高精度算法。
一、简介高精度算法
1.什么是高精度算法
高精度算法,属于处理大数字的数学计算方法。在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几千亿几百亿的大数字。一般这类数字我们统称为高精度数,高精度算法是用计算机对于超大数据的一种模拟加,减,乘,除,乘方,阶乘,开方等运算。
以上内容来自高精度算法_360百科
2.高精度算法的应用范围
高精度算法的应用范围说广也广,说不广也不广。他不想排序那样能够运用到搜索、贪心甚至数据结构方面,而且在一定程度上高精度算法过于繁琐(大部分题目的数据long long及以下就可以解决)。 但是对于某些热衷于暴力求解的童鞋(比如我)来说,在遇到某些需要暴力+优化的题目时,可以不考虑优化,直接运用高精度算法来求解。😌
二、高精度算法的实现
1.高精度算法之加法
高精度加法是利用数组来模拟加法 先举个例子:194+256
??????194
+ ???256 ———— ??????650
数字 | 第4位 | 第3位 | 第2位 | 第1位 |
---|
194 | | 1 | 9 | 4 | 256 | | 2 | 5 | 6 | 中间结果 | | 3 | 14 | 10 | 进位处理 | | 5 | 15 | 0 | 进位处理 | | 4 | 5 | 0 | 结果 | | 4 | 5 | 0 |
从以上表格中可以看到加法是同时进行的,而进位必须从低位到高位来实现。而在代码实现中可以加法和进位同时进行,以提高效率。
代码实现
#include<stdio.h>
#include<string.h>
#define MAXN 1000
int a[MAXN],b[MAXN],c[MAXN];
int main(){
char s[MAXN],ss[MAXN];
scanf("%s%s",s,ss);
int sta=strlen(s),stb=strlen(ss);
int len=sta>stb?sta:stb;
for(int i=sta-1,j=0;i>=0;i--,j++)a[j]=s[i]-'0';
for(int i=stb-1,j=0;i>=0;i--,j++)b[j]=ss[i]-'0';
for(int i=0;i<len;i++){
c[i]+=a[i]+b[i];
c[i+1]=c[i]/10;
c[i]%=10;
}
if(c[len]){
len++;
}
for(int i=len-1;i>=0;i--){
printf("%d",c[i]);
}
return 0;
}
2.高精度算法之乘法
同理,高精度乘法也是利用数组来模拟两数相乘
?? ???????194 x ???????256 ————— ????????1164 ????????970 ??????388 ??????49664
数字 | 第5位 | 第4位 | 第3位 | 第2位 | 第1位 |
---|
194 | | | 1 | 9 | 4 | 256 | | | 2 | 5 | 6 | 中间步骤 | | 1 | 1 | 6 | 4 | 中间步骤 | | 9 | 7 | 0 | | 中间步骤 | 3 | 8 | 8 | | | 进位处理 | 3 | 18 | 16 | 6 | 4 | 进位处理 | 3 | 19 | 6 | 6 | 4 | 进位处理 | 4 | 9 | 6 | 6 | 4 | 最终结果 | 4 | 9 | 6 | 6 | 4 |
乘法的整个过程体现在表格中,观察表格,可以发现第i+j-1格(代码化)上是由数字一[i] * 数字二[j],可以一起先全部加起来再进位,提高效率。
#include<stdio.h>
#include<string.h>
#define MAXN 10000
int a[MAXN],b[MAXN],c[MAXN];
int main(){
char s[MAXN],ss[MAXN];
scanf("%s%s",s,ss);
int sta=strlen(s),stb=strlen(ss);
for(int i=sta-1;i>=0;i--)a[sta-i]=s[i]-'0';
for(int i=stb-1;i>=0;i--)b[stb-i]=ss[i]-'0';
for(int i=1;i<=sta;i++){
for(int j=1;j<=stb;j++){
c[i+j-1]+=a[i]*b[j];
}
}
int len=sta+stb;
for(int i=1;i<=len;i++){
c[i+1]+=c[i]/10;
c[i]%=10;
}
while(!c[len]){
len--;
}
for(int i=len>1?len:1;i>=1;i--){
printf("%d",c[i]);
}
return 0;
}
以上代码部分借鉴于洛谷(本人技术有限😭)
三、总结
高精度算法对于暴力来说还是有一定应用范围的,特别是头疼于时间复杂度与空间复杂度时,高精度计算可以避免陷入第三次头疼。
这是本人第一次写博客,如有喜欢,望好评🙂
|