//作者 陈奕霖&陈立哲
//每行 代码有详细注释 附录1,2见 代码后 。本代码为C++信息学竞赛生提供 仅做参考
计算两个非负整数 A,B 的乘积,A,B 可能会很大。
输入格式
第一行输入一个非负整数 A。
第二行输入一个非负整数 B。
A,B 的长度不大于 500。
输出格式
输出 A×B 的值。
样例输入
4321 1234
样例输出
5332114
#include<iostream>
#include<iostream>
#include<algorithm>using namespace std;
const int MAX =2000; //用2000而不是500做最大长度是由于长度为n的两个正整数乘积位数最大为2*n
int A[MAX],B[MAX],Ans[MAX],Len_A,Len_B,Len_Ans; //定义a,b,a和b乘积的长度与数位
void Read(int *A,int &Len){ //*表示赋值的为数组,&表示改变该变量值时同时改变原始变量
string cur; //将要输入的数值以文本形式保留下来方便以后访问
cin>>cur; //读入第一个值
Len=cur.length(); //读取输入的数的长度
for(int i=0;i<Len;i++)A[i]=cur[i]-48; //将每一个数值输入到数组的每一个单位中,-48是由于将字符转换为数字时要增加48个单位的值
reverse(A,A+Len); //将数字反转,方便处理
}
int main(){//略
Read(A,Len_A) ; //读入第一个值
Read(B,Len_B); //读入第二个值
Len_Ans=Len_A+Len_B-1; //总长度
for(int i=0;i<Len_Ans;i++){
for(int j=0;j<Len_B;j++)
Ans[i+j]+=A[i]*B[j]; // 见附录1(详见代码后)
}
for(int i=0;i<Len_Ans;i++){
if(Ans[i]>9)Ans[i+1]+=Ans[i]/10,Ans[i]%=10; //判断是否需要进位
}
while(Ans[Len_Ans])Len_Ans ++; //进位
if(Ans[0]==0 and Ans[1]==0 and Ans[2]==0)cout<<"0"; //排除有一个数是0的情况,因为0*0=0,不输入则会有多余的前导零
else for(int i=Len_Ans-1;i>=0;i--)cout<<Ans[i]; //将乘积的数组依次输出以构成数
return 0;
}
附录1:
若a={5,3} b={4,7},设有枚举变量i,j
1)i=0,j=0,ans[i+j]=ans[1]=ans[0]*b[0]=21
2)i=0,j=1,ans[i+j]=ans[1]=a[0]*b[1]=12
3)i=1,j=0,ans[i+j]=ans[1]=ans[1]+a[1]*b[0]=12+35=47
4)i=1,j=1,ans[i+j]=ans[2]=ans[1]*b[1]=20
以此类推,ans={20,47,21}时,低位向高位进位,最终得{2,4,9,1}
附录2:
关于reverse
语法:reverse(string)
要颠倒字符次序的字符串返回值String。函数执行成功时返回颠倒字符次序后的字符串,如果发生错误,那么返回空字符串("")。用法Reverse()函数将一个字符串中最后一个字符放置到另一个字符串的第一个字符位置、倒数第二个字符放置在另一个字符串的第二个字符位置,以此类推。
(摘自百度百科)
关于reverse
语法:reverse(string)
要颠倒字符次序的字符串返回值String。函数执行成功时返回颠倒字符次序后的字符串,如果发生错误,那么返回空字符串("")。用法Reverse()函数将一个字符串中最后一个字符放置到另一个字符串的第一个字符位置、倒数第二个字符放置在另一个字符串的第二个字符位置,以此类推。
(摘自百度百科)