链接:
https://www.nowcoder.com/acm/contest/118/E
来源:牛客网
Kirai其实十分高冷,他发现了这个问题。为了不希望别人立刻知道他在笑,他决定将两个“233..”乘在一起发出去。
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
空间限制: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;
}