这篇文章也是去年写的,我又忘记发布了…
大数加法-任意A+B:hdu 1002 A + B Problem II
高精度计算大数加法,把输入的a1、b1这两个字符数组逆序保存到整型数组a、b中,这样可以在a、b前自动添0。
#include <bits/stdc++.h>
using namespace std;
string a1,b1;
int c,n,cas,tmp,cnt1,cnt2,maxlen,a[1010],b[1010],ans[1010];
int main()
{
cin>>n;
for(cas=1;cas<=n;cas++)
{
cin>>a1>>b1;
printf("Case %d:\n",cas);
printf("%s + %s = ",a1.c_str(),b1.c_str());
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
cnt1=cnt2=0;
for(int i=a1.length()-1;i>=0;i--)
a[++cnt1]=a1[i]-'0';
for(int i=b1.length()-1;i>=0;i--)
b[++cnt2]=b1[i]-'0';
maxlen=max(cnt1,cnt2);
c=0;//c表示进位
for(int i=1;i<=maxlen+1;i++)
{
tmp=a[i]+b[i]+c;
if(tmp>=10){ans[i]=tmp-10;c=1;}
else {ans[i]=tmp;c=0;}
}
if(ans[maxlen+1]==0)printf("%d",ans[maxlen+1]);
for(int i=maxlen;i>=1;i--)
printf("%d",ans[i]);
cas==n?printf("\n"):printf("\n\n");
}
return 0;
}
大数乘法-任意A*B:poj 2389 Bull Math
写代码之前先在纸上用笔模拟乘法运算的过程,用二维数组t保存乘法计算的中间过程的结果。
#include <cstdio>
#include <iostream>
using namespace std;
string tmpa,tmpb;
int a[105],b[105],ans[105],t[105][105],c,tmps,lena,lenb,anslen;//模拟乘法运算,二维数组t保存乘法计算的中间过程的结果
int main()
{
cin>>tmpa>>tmpb;
if(tmpa=="0"||tmpb=="0"){printf("0\n");return 0;}
lena=lenb=0;
for(int i=tmpa.length()-1;i>=0;i--)
a[++lena]=tmpa[i]-'0';
for(int i=tmpb.length()-1;i>=0;i--)
b[++lenb]=tmpb[i]-'0';
anslen=lena+lenb;
for(int i=1;i<=lenb;i++)
{
c=0;//c表示进位
for(int j=1;j<=lena+1;j++)
{
tmps=a[j]*b[i]+c;
c=tmps/10;
t[i][i+j-1]=tmps%10;//注意i+j-1,保证之后的对齐相加
}
}
c=0;//c表示进位
for(int i=1;i<=anslen;i++)//把二维数组t的各个数对齐相加
{
for(int j=1;j<=lenb;j++)
{ans[i]=ans[i]+t[j][i];}
ans[i]=ans[i]+c;
c=ans[i]/10;
ans[i]=ans[i]%10;
}
if(ans[anslen]==0)anslen--;
for(int i=anslen;i>=1;i--)
printf("%d",ans[i]);
printf("\n");
return 0;
}
大数乘法-从1乘到n:hdu 1042 N!
高精度计算N的阶乘,从1开始,用大数乘法的方式依次乘到n,用斯特林(Stirling)公式计算阶乘的位数(需要定义自然常数和圆周率),最后逆序输出即可。
//hdu 717ms
#include <bits/stdc++.h>
#define e 2.7182818284//自然常数
#define p acos(-1.0)//圆周率
using namespace std;
int n,c,l,tmp,ans[36000];//10000!的位数是35660
int main()
{
while(cin>>n)
{
if(n==0){printf("1\n");continue;}
memset(ans,0,sizeof(ans));
l=0;ans[0]=1;
for(int i=1;i<=n;i++)
{
c=0;//c表示进位
l=(int)(log10(2*p*i)*0.5+i*log10(i/e))+1;//利用斯特林(Stirling)公式求解 i! 的位数
for(int j=0;j<l;j++)
{
tmp=ans[j]*i+c;//把答案数组的每一位依次乘i再加进位
c=tmp/10;
ans[j]=tmp%10;
}
}
for(int i=l-1;i>=0;i--)
printf("%d",ans[i]);
printf("\n");
}
return 0;
}
大数乘法 50000位数,待解决:hdu 1402 http://acm.hdu.edu.cn/showproblem.php?pid=1402