题目:
Bull Math
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 12786 | Accepted: 6584 |
Description
FJ asks that you do this yourself; don't use a special library function for the multiplication.
Input
Output
Sample Input
11111111111111
1111111111
Sample Output
12345679011110987654321
Source
[Submit] [Go Back] [Status] [Discuss]
中文翻译:
公牛在数学方面与奶牛相比要好很多,他们可以把巨大的数相乘得到完美精确地答案!农场主约翰就请你编程验证答案是否正确,给出两个不超过40位的正整数,计算出乘积(无前导0)
每个数据一行,输出一行。
题目大意:
计算两个不超过40位的大数相乘
解题思路:
因为大数是说的:一、数值大 二、精确度高,
本题因为是整数的相乘,所以就不涉及精确度的问题,只需考虑数值的大小。
存储:
要计算两个数相乘,需要先输入,然后存储下来,再进行计算,由于数值较大,一般的整形变量难以正确存储,所以可以借助数组进行数据的存储。
运算:
本题的数据在40位以内,不算太大,可以直接模拟乘法运算,(对于较大的数需要采用傅里叶转换),最后再进行进位处理。
输出:
输出时要去除前导0;对此,可以采用将数倒置放入数组中,以个位对齐,得运算结果,然后逆序输出,(过滤掉前导0)。
关键点:
1、先像大数加法那样,进行存储数据
2、乘法的模拟运算
3、去除前导0
难点:
乘法模拟:
在进行运算时相乘得到的结果应该存储到对应的位置
for(i=0;i<l1;i++){
for(j=0;j<l2;j++){
a[i+j]+=b1[i]*b2[j];
}
即:b1[i]*b2[j]应该存储在a数组对应的i+j+1位上,也即a[i+j] 、(a[0]为第一个元素)
进位处理 :
之前的代码
for(i=0;i<M*2;i++){
s=a[i];
for(j=i;;j++){ //此处是计算的核心部分,尤其是将a[i]分解加到高位上时
if(j==i)
a[j]=a[j]%10; //本位就是自身对10的余数。而其他位的要加上来自后面的进位,,也即将自身的个位留下,将高位逐个加到前面去
else
a[j]=a[j]+s%10;
s/=10;
if(s==0)
break;
}
后来发现根本不需要这么麻烦,因为在这一步只需得到这一为的值即可,多出来的都加到高位,无需精确加到了哪一位,因为高位的值还不真正确定,只需后来对其做同样处理,确定即可:
优化如下:
if(a[i]>=10)
{
a[i+1]+=a[i]/10; //注意:此处要加在前一位上,而不是直接赋值
a[i]%=10;
}
源代码:
# include<stdio.h>
# include<string.h>
# define M 50
char c1[M+50],c2[M+50];
int b1[M+50],b2[M+50];
int a[2*M+50];
int main(){
int i,j,k,l;
int l1,l2;
int t,s;
while(~scanf("%s%s",c1,c2)){
memset(b1,0,sizeof(b1));
memset(b2,0,sizeof(b2));
memset(a,0,sizeof(a));
l1=strlen(c1);
l2=strlen(c2);
for(i=l1-1,j=0;i>=0;i--){
b1[j++]=c1[i]-'0';
}
for(i=l2-1,j=0;i>=0;i--){
b2[j++]=c2[i]-'0';
}
for(i=0;i<l1;i++){
for(j=0;j<l2;j++){
a[i+j]+=b1[i]*b2[j];
}
}
for(i=0;i<M*2;i++){
/* s=a[i];
for(j=i;;j++){ //此处是计算的核心部分,尤其是将a[i]分解加到高位上时
if(j==i)
a[j]=a[j]%10; //本位就是自身对10的余数。而其他位的要加上来自后面的进位,,也即将自身的个位留下,将高位逐个加到前面去
else
a[j]=a[j]+s%10;
s/=10;
if(s==0)
break;
}
*/
if(a[i]>=10)
{
a[i+1]+=a[i]/10; //注意:此处要加在前一位上
a[i]%=10;
}
}
for(i=M*2+10;i>=0&&a[i]==0;i--);
if(i>=0)
{
for(;i>=0;i--)
printf("%d",a[i]);
printf("\n");
}
else
printf("0\n");
}
return 0;
}
解题体会:
做这样的题的时候,模拟运算也是很重要的!
解题人:李富昌