2018年北京信息科技大学第十届程序设计竞赛暨ACM选拔赛 E 233(大数相乘)

链接: https://www.nowcoder.com/acm/contest/118/E
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述


Kirai聊天的时候非常喜欢发“233”,“233”来源于猫扑表情第233号,是一张捶地大笑的表情。
Kirai每当看到很好玩的消息的时候总会回一串“2333...”。
Kirai其实十分高冷,他发现了这个问题。为了不希望别人立刻知道他在笑,他决定将两个“233..”乘在一起发出去。

输入描述:

输入样例有多组,全部是正整数。首先输入样例组数T(T≤1500)。
接下来输入T组数,每组数字由两个233串组成,每个233串长度3≤n≤50。
数据保证每个233串必然会有一个2作为开头,并且3的数量≥2。

输出描述:

两个233串的乘积。

模拟乘法累加 -

简单来说,就是先不算任何的进位,也就是说,将每一位相乘,相加的结果保存到同一个位置,到最后才计算进位

例如:计算98×21,步骤如下

        9  8
×       2  1
-------------
       (9)(8)  <---- 第1趟: 98×1的每一位结果 
  (18)(16)     <---- 第2趟: 98×2的每一位结果 
-------------
  (18)(25)(8)  <---- 这里就是相对位的和,还没有累加进位 

这里唯一要注意的便是进位问题,我们可以先不考虑进位,当所有位对应相加,产生结果之后,再考虑。

从右向左依次累加,如果该位的数字大于10,那么我们用取余运算,在该位上只保留取余后的个位数,

而将十位数进位(通过模运算得到)累加到高位便可,循环直到累加完毕。

 
 
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
 
char num1[100];
char num2[100];
int a[100];
int b[100];
int c[210];
 
void multiply(char num1[],char num2[])
{
    int len1=strlen(num1);
    int len2=strlen(num2);
    int i,j=0;
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    memset(c,0,sizeof(c));
    for(i=len1-1;i>=0;i--)
        ///反向储存,为了后面的进位可以向后扩展储存;
    {
        a[j++]=num1[i]-'0';
    }
    j=0;
    for(i=len2-1;i>=0;i--)
    {
        b[j++]=num2[i]-'0';
    }
    for(i=0;i<len2;i++)
    {
        for(j=0;j<len1;j++)
        {
            c[i+j]+=b[i]*a[j];// 先不考虑进位问题,根据竖式的乘法运算,num1的第i位与num2的第j位相乘,结果应该存放在结果的第i+j位上
        }
    }
    for(i=0;i<210;i++)//单独处理进位
    {
        if(c[i]>=10)
        {
            c[i+1]=c[i+1]+c[i]/10;
            c[i]=c[i]%10;
        }
    }
    for(i=210;i>=0&&c[i]==0;i--);//处理掉多余的0
    for(;i>=0;i--)
    {
        cout<<c[i];
    }
    cout<<endl;
}
 
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        scanf("%s%s",num1,num2);
        multiply(num1,num2);
 
    }
    return 0;
}



猜你喜欢

转载自blog.csdn.net/qq_41668093/article/details/80245571
今日推荐