poj中的大数乘法!
来源:互联网 发布:二号首长 知乎 编辑:程序博客网 时间:2024/05/24 06:50
题目:
Bull Math
Description
FJ asks that you do this yourself; don't use a special library function for the multiplication.
Input
Output
Sample Input
111111111111111111111111
Sample Output
12345679011110987654321
Source
[Submit] [Go Back] [Status] [Discuss]
Home Page Go Back To top
中文翻译:
公牛在数学方面与奶牛相比要好很多,他们可以把巨大的数相乘得到完美精确地答案!农场主约翰就请你编程验证答案是否正确,给出两个不超过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;
}
解题体会:
做这样的题的时候,模拟运算也是很重要的!
解题人:李富昌
- poj中的大数乘法!
- POJ 2389 大数乘法
- POJ 2389大数乘法
- poj 2389 大数乘法
- poj 2109 二分+大数乘法
- poj 2389 BullMath(大数乘法)
- 大数乘法 poj 2389 ||大数乘法 hdu1402 FFT模板
- 简单题POJ-1001,大数乘法
- POJ--2389:Bull Math 大数乘法
- 大数乘法——POJ 1001
- POJ 1001 Exponentiation (高精度/大数乘法)
- POJ 1001 Exponentiation 大数乘法模拟
- poj 2389 解题报告 大数乘法
- 大数乘法
- 大数乘法
- 大数乘法
- 大数乘法
- 大数乘法
- leetcode之Path Sum
- 如何用VC编写动态链接库(DLL)
- ubuntu打开txt中文乱码解决
- 一些周期性GC的原因
- UVa 567 - Risk
- poj中的大数乘法!
- hdu1978How many ways(记忆化搜索)(基于深搜)
- 完全背包变形--hdu-1114-Piggy-Bank
- C++命名规范
- poj 2255 Tree Recovery(二叉树的遍历)
- flash builder + AS json解析
- 如何查看某个网站的ip地址(根据域名怎么知道IP)
- 修改对话框中所有控件的窗口样式
- 【ZOJ】2676 Network Wars 01分数规划+最小割