大数相乘问题的基本思想 a*b=c;用d[i]表示每一位数字,a.d[i]*b.d[j]=c.d[i+j]。但是我们需要考虑c.d[i+j]大于10的可能,所以要对它进行取余进位。另一个为题,就是如果算的是a^n方的话,是需要用矩阵快熟幂的。
//大数相乘问题a*b=c
//思路是d[i]表示乘数的每一位,从0开始。a.d[i]*b.d[j]=c.d[i+j]
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=1e5;
class bignum{
public:
int d[maxn];//每一位
int len;//长度
bignum()
{
memset(d,0,sizeof(d));
}
bignum(int x)
{
int l=0;
memset(d,0,sizeof(d));
while(x)
{
d[l++]=x%10;//保存每一位
x/=10;
}
len=l;
}
bignum operator*(const bignum &res)const
{
bignum ans;
for(int i=0;i<this->len;i++)//根据手算乘法的过程进行计算
{
for(int j=0;j<res.len;j++)
{
ans.d[i+j]+=d[i]*res.d[j];
}
}
for(int i=0;i<this->len+res.len;i++)//因为存在a.d[i]*b.d[j]大于10的情况,所以要进行求余
{
ans.d[i+1]+=ans.d[i]/10;//进位
ans.d[i]=ans.d[i]%10;//剩下来的位
}
int Len=this->len+res.len;//算出有多少位
while(Len>1&&ans.d[Len-1]==0)
{
Len--;//在此处陷入了死循环
}
ans.len=Len;
return ans;
}
bignum operator^(const int x)const
{
bignum ans(1);
bignum res;
res.len=this->len;
int term=x;
for(int i=0;i<this->len;i++)
{
res.d[i]=this->d[i];
}
while(term)//快速幂
{
if(term&1)
{
ans=ans*res;
}
term>>=1;
res=res*res;
}
return ans;
}
void print()
{
for(int i = len - 1; i >= 0; i--)
{
printf("%d",d[i]);
}
printf("\n");
}
};
int main()
{
int T;
cin>>T;
for(int k=1;k<=T;k++)
{
int n;
cin>>n;
printf("Case #%d: ",k);
bignum ans(32);
ans=ans^n;
ans.print();
}
return 0;
}