高精度模板
[高精度加法]例题 一、P601洛谷:A+B Problem(高精)
P601洛谷
A+B Problem(高精)
题目背景
无
题目描述
高精度加法,x相当于a+b problem,b不用考虑负数。
输入输出格式
输入格式:
分两行输入a,b<=10^500
输出格式:
输出只有一行,代表A+B的值
输入输出样例
输入样例#1:
1
1
输出样例#1
1
1.C/C++模板1[详细版]
#include<bits/stdc++.h>
using namespace std;
int a[501],b[501];//长度是位数
void add(string s1,string s2)
{
int i,j,len1,len2;
char s[501];
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
len1=s1.length();
len2=s2.length();
//把两个字符串转换成整数
for(i=len1-1;i>=0;i--)
a[i]=s1[len1-1-i]-'0';//s1=123,a=321
for(i=len2-1;i>=0;i--)
b[i]=s2[len2-1-i]-'0';//s2=12 , b=21
// s1+s2=123+12=135 ,a+b=321+21=531 取个反就对了
int c=0;//进位
j=0;
while(j<=max(len1,len2))//运算到0-max(len1,len2)位max(len1,len2)位可能是0
{
a[j]=a[j]+b[j]+c;
if(a[j]>=10)//进位
{
a[j]-=10;
c=1;
}
else//否则不进位
c=0;
j++;
}
int k=max(len1,len2);
while(a[k]==0&&k>=1)//k>=1一定要加啊
k--;//去掉后面的0 即max位如果是0 则去掉
for(j=k;j>=0;j--)
s[j]=a[k-j]+'0';
s[k+1]='\0';printf("%s\n",s);
//for(i=0;i<=k;i++)
//printf("%c",s[i]);
// printf("\n");
return;
}
int main(void)
{
string s1,s2;
while(cin>>s1>>s2)
add(s1,s2);
return 0;
}
2.python(三行代码)
python:
由于python的int是无长度限制的数据类型,理论上是无限长。所以python的高精度对于c++/c语言来说就像玩的一样。
AC代码:
a = input()
b = input()
print(int(a) + int(b))
不过时间复杂度上,C++/C更快
[高精度加法]例题二、蓝桥杯基础练习 高精度加法
资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
输入两个整数a和b,输出这两个整数的和。a和b都不超过100位。
算法描述
由于a和b都比较大,所以不能直接使用语言中的标准数据类型来存储。对于这种问题,一般使用数组来处理。
定义一个数组A,A[0]用于存储a的个位,A[1]用于存储a的十位,依此类推。同样可以用一个数组B来存储b。
计算c = a + b的时候,首先将A[0]与B[0]相加,如果有进位产生,则把进位(即和的十位数)存入r,把和的个位数存入C[0],即C[0]等于(A[0]+B[0])%10。然后计算A[1]与B[1]相加,这时还应将低位进上来的值r也加起来,即C[1]应该是A[1]、B[1]和r三个数的和.如果又有进位产生,则仍可将新的进位存入到r中,和的个位存到C[1]中。依此类推,即可求出C的所有位。
最后将C输出即可。
输入格式
输入包括两行,第一行为一个非负整数a,第二行为一个非负整数b。两个整数都不超过100位,两数的最高位都不是0。
输出格式
输出一行,表示a + b的值。
样例输入:
20100122201001221234567890
2010012220100122
样例输出:
20100122203011233454668012
C/C++模板2[精简版]
上面的模板1其实就是初学的时候模范别人打的有点乱,但是原理清楚,建议用这个作为参考。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char a[105];char b[105];int sum[150];
void solve()
{
int c=0;
int lena=strlen(a);int lenb=strlen(b);
int k=max(lena,lenb);
//翻转:位数对齐(列竖式)
/*for(int i=0;i<lena/2;i++) swap(a[i],a[lena-i-1]);
for(int i=0;i<lenb/2;i++) swap(b[i],b[lenb-i-1]);*///和下面一行等价
reverse(a,a+lena);reverse(b,b+lenb);
int j=0;
while(j<k||c!=0)
{
int na=0,nb=0;
if(j<lena) na=a[j]-'0';
if(j<lenb) nb=b[j]-'0';
sum[j]=(na+nb)+c;
c=sum[j]/10;
sum[j]%=10;
j++;
}
while(sum[k]==0&&k>0) k--;
for(int i=k;i>=0;i--)
printf("%d",sum[i]);
printf("\n");
return;
}
int main(void)
{
scanf("%s",a);
scanf("%s",b);
solve();
return 0;
}
[高精度减法]模板(C++)
#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
using namespace std;
bool compare(string a,string b)
{
if(a.size()>b.size()) return true;
if(a.size()<b.size()) return false;
if(a>=b)//长度相等才比
return true;
return false;
}
void subtraction(string a,string b)
{
int len=a.size();
int sa[20005],sb[20005];
for(int i=0;i<len;i++) sa[i]=a[len-i-1]-'0';
for(int i=0;i<len;i++) sb[i]=0;
len=b.size();
for(int i=0;i<len;i++) sb[i]=b[len-i-1]-'0';
len=a.size();
int c[20005];
int z=0;
for(int i=0;i<len;i++){
z=sa[i]-sb[i];
if(z<0)
{
int j=i+1;
while(sa[j]-1<0&&j<len)
{
sa[j]=9;
j++;
}
sa[j]-=1;
if(sa[j]==0&&j==len-1) len--;
z+=10;
}
c[i]=z;
}
int k=len-1;
while(k>0&&c[k]==0) k--;
for(int i=k;i>=0;i--)
printf("%d",c[i]);
printf("\n");
return;
}
int main(void)
{
string a,b;
cin>>a;
cin>>b;
if(!compare(a,b)){
swap(a,b);
printf("-");
}
subtraction(a,b);
return 0;
}
或许题解中的另一个方法更简单,但是上面代码更符合我们日常习惯吧。
[高精度乘法]模板C++
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
bool compare(string a,string b)
{
if(a.size()>b.size())
return true;
return false;
}
int a[85],b[85],w[85];
void solve(string sa,string sb)
{
int lena=sa.size(),lenb=sb.size();
for(int i=0;i<lena;i++) a[i]=sa[lena-i-1]-'0';
for(int i=0;i<lenb;i++) b[i]=sb[lenb-i-1]-'0';
int c=0,z=0;
for(int i=0;i<lenb;i++){
for(int j=0;j<lena;j++){
z=b[i]*a[j]+c;
c=z/10;
w[j+i]+=z%10;
//注意加法进位
if(w[j+i]>=10)
{
c+=w[j+i]/10;
w[j+i]%=10;
}
}
if(c)
{
w[lena+i]+=c;
c=0;
}
}
int k=84;
while(k>0&&w[k]==0) k--;
for(int i=k;i>=0;i--) printf("%d",w[i]);
puts("");
return;
}
int main(void)
{
string a,b;
cin>>a;
cin>>b;
if(!compare(a,b))
swap(a,b);
solve(a,b);
return 0;
}
高精度除法
高精度除法要用到高精度减法,其中减法用于试商,而不是用高精度乘法。
高精度除法还没打,就用了一下其他博主的代码块,理清楚思路,相信能自己敲出来
步骤如下:
1、将除数和被除数对齐,被除数位数不够时,补0。
2、利用被除数减去除数,一直减到被除数小于除数,减的次数,就是“试商”的结果,每减一次当前位结果就加一个。
3、重复上述步骤,一直到被除数和除数的位数相等为止(求得余数)或者达到某一精度要求。