3117 高精度练习之乘法——http://codevs.cn/problem/3117/
第一部分:题目
题目描述 Description
给出两个正整数A和B,计算A*B的值。保证A和B的位数不超过500位。
输入描述 Input Description
读入两个用空格隔开的正整数
输出描述 Output Description
输出A*B的值
样例输入 Sample Input
3 12
样例输出 Sample Output
36
数据范围及提示 Data Size & Hint
两个正整数的位数不超过500位
第二部分:思路
高精度整数乘法又叫做大整数乘数。原理就是分解为多个大整数加法。怎么分解呢?用短的数作为乘数,长的数作为被乘数,这样方便计算。(不信的话你一步一步笔算123456*123,123*123456.)123456*123可以分解成:123456*3+123456*20+123456*100.注意到3、2、1数值变大。就是多个1、2个0.这里稍微注意下就可以了。剩下的就是大整数加法了。请看本小白的相关文章。
第三部分:代码
#include<stdio.h> #include<string.h> int result[1000],length=0; void repai(char s[500],int len)//把数组倒置 { int i,j=len-1; char t; for(i=0;i<j;i++) { j=len-i-1;//相当于以中点对折。 t=s[i]; s[i]=s[j]; s[j]=t; } } void plus(int a[501],int alen)//加法 { int i,t,flag=0; for(i=0;i<alen&&i<length;i++)//从个位开始相加 { t=a[i]+result[i]+flag; if(t>9)//判断是否需要进位 { t-=10; flag=1; } else//当前不需要进位时置为0 { flag=0; } result[i]=t; } while(i<alen) { t=a[i]+flag; if(t>9) { t-=10; flag=1; } else { flag=0; } result[i]=t; i++; } while(i<length) { t=result[i]+flag; if(t>9) { t-=10; flag=1; } else { flag=0; } result[i]=t; i++; } length=i; if(flag) { result[length++]=1; } } void compute(char a[500],int alen,char b[500],int blen)//进行乘法计算 { int i,j,flag=0; repai(a,alen);//倒置 repai(b,blen); int t,temp[501],len;//使用中间值数组temp暂时存储每一步乘积 for(i=0;i<blen;i++)//从个位开始相减 { len=0; for(j=0;j<i;j++) { temp[len++]=0; } for(j=0;j<alen;j++) { t=(b[i]-'0')*(a[j]-'0')+flag; if(t>9) { flag=t/10; t-=flag*10; } else { flag=0; } temp[len++]=t; } if(flag>0)//这里需要注意一下:flag>0表示当前乘法结果由n位数变成了n+1位数。 { temp[len++]=flag; flag=0; } plus(temp,len);//每一步乘积加到最终结果 } } int main() { char a[500],b[500];//接收数a、b scanf("%s %s",a,b); int alen,blen; alen=strlen(a);//数组a、b长度 blen=strlen(b); if(alen<blen)//长的作为被乘数,短的作为乘数 { compute(b,blen,a,alen); } else { compute(a,alen,b,blen); } int i; for(i=length-1;i>=0;i--) { printf("%d",result[i]); } printf("\n"); return 0; }
害怕失败的人,已经是一个loser!