信息学奥赛一本通(1174:大整数乘法)

1174:大整数乘法


时间限制: 1000 ms         内存限制: 65536 KB
提交数: 12480     通过数: 7002

【题目描述】

求两个不超过200位的非负整数的积。

【输入】

有两行,每行是一个不超过200位的非负整数,没有多余的前导0。

【输出】

一行,即相乘后的结果。结果里不能有多余的前导0,即如果结果是342,那么就不能输出为0342。

【输入样例】

12345678900
98765432100

【输出样例】

1219326311126352690000

【分析】

【参考代码】

C代码:

#include <stdio.h>
#include <string.h>
#define MAXN 10010

char s1[MAXN],s2[MAXN];
int a[MAXN],b[MAXN],c[MAXN];

int main()
{
	int i,j,flaga=1,flagb=1;
	int lena,lenb,lenc,jw; 
	 
	//读入字符串
	scanf("%s %s",s1,s2);
	
	//符号处理,1表示正数,0表示负数
	if(s1[0]=='-')
	{
		flaga=0;
		strcpy(&s1[0],&s1[1]);
	}
	if(s2[0]=='-')
	{
		flagb=0;
		strcpy(&s2[0],&s2[1]);
	}
	
	//送入整数数组
	lena=strlen(s1);
	for(i=0;i<lena;i++)
	{
		a[i]=s1[lena-i-1]-'0';
	}
	lenb=strlen(s2);
	for(i=0;i<lenb;i++)
	{
		b[i]=s2[lenb-i-1]-'0';
	}
	
	//模拟竖式乘法
	for(i=0;i<lena;i++)
	{
		jw=0;  //上一轮计算进位
		for(j=0;j<lenb;j++)
		{
			//交叉乘积
			c[i+j]=a[i]*b[j]+jw+c[i+j]; //当前乘积+上次乘积进位+原数 
			jw=c[i+j]/10;  //处理进位
			c[i+j] %=10;
		}
		c[i+lenb]=jw;   //进位设置 
	}
	
	//删除前导零
    lenc=lena+lenb;
    for(i=lenc-1;i>=0;i--)
	{
        if(c[i]==0 && lenc>1)
            lenc--;
		else
            break;
    }
    
    //逆序打印输出
    for(i=lenc-1;i>=0;i--)
        printf("%d", c[i]);
    printf("\n");
    
	return 0;
}

C++代码:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

// C = A * B, A >= 0, B > 0
vector<int> mul(vector<int> &A, vector<int> &B)
{
    vector<int> C(A.size()+B.size(),0);  // 初始化为 0, 且999*99最多 5 位
    
    for(int i=0;i<A.size();i++)
        for(int j=0;j<B.size();j++)
            C[i+j]+=A[i]*B[j];
    
    int t=0;  //进位 
    for(int i=0;i<C.size();i++)
    {
        t+=C[i];
        C[i]=t%10;
        t/=10;
    }
    while(C.size()>1 && C.back()==0)
        C.pop_back();

    return C;
}

int main()
{
    string a,b;
    vector <int> A,B;
    
    cin >> a >> b;
    for(int i=a.size()-1; i>=0; i--)
        A.push_back(a[i]-'0');
    
    for(int i=b.size()-1; i>=0; i--)
        B.push_back(b[i]-'0');
    
    vector <int> C=mul(A,B);
    
    for(int i=C.size()-1;i>=0;i--)
        cout << C[i];
    cout<<endl;
    
    return 0;
}

http://ybt.ssoier.cn:8088/problem_show.php?pid=1174

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值