特殊乘法 - 九度教程第39题
题目:
时间限制:1 秒 内存限制:32 兆 特殊判题:否
题目描述:
写个算法,对 2 个小于 10 0000 0000 的输入,求结果。
特殊乘法举例:123 * 45 = 14 +15 +24 +25 +34+35
输入:
两个小于 1000000000 的数
输出: 输入可能有多组数据,对于每一组数据,输出 Input 中的两个数按照题目 要求的方法进行运算后得到的结果。
样例输入:
123 45
样例输出:
54
来源:
2010 年清华大学计算机研究生机试真题
解析:
核心任务是将两个整数各个数位上的数字拆开,然后再将这些数字两两相乘后求和得到答案。如样例所示, 将整数 123 拆解成 1、2、3,将整数 45 拆解成 4、5,然后将它们两两相乘后相加就得到了答案54。
设输入的数为x,对x做整除,使x除以整数10,即可将十位上的数字移动到个位上,百位上的数字移动到十位数字,其他位依次类推。重复求个位数字的方法,即得到已经移动到个位的数字。
不断地重复对x除以10,对10求模,即可得到数字x各个数位上的数字。
代码1:(利用数学原理,不断对10取模、除以10)
#include<stdio.h>
int main()
{
int a,b; //保存两个整数的变量
while(scanf("%d%d",&a,&b)!=EOF)//输入两个整数
{
int buf1[20],buf2[20],size1=0,size2=0;
//用buf1,buf2分别保存从两个整数中拆解出来的数位数字,其数量由size1,size2表示
while(a!=0) //数位拆解,只要当a依然大于零就不断重复拆解过程
{
buf1[size1++]=a%10; //取得当前个位数上的数字,将其保存
a/=10; //将所有数位上的数字移动到高一位上
}
while(b!=0) //拆解第二位数字
{
buf2[size2++]=b%10;
b/=10;
}
int ans=0; //计算答案
for(int i=0;i<size1;i++)
{
for(int j=0;j<size2;j++)
{
ans+=buf1[i]*buf2[j];//两两相乘后相加
}
}
printf("%d\n",ans);
}
return 0;
}
代码2:(将输入数据当作字符串)
代码1完成数位拆解的方法是从数学原理出发的。接下来的另一种数位拆解的过程,它将绕过数学原理,采用较为投机的方法。
不再用整数变量来保存输入的数字,再利用求模、求商等数学方法得到拆解后的数字。而是转而直接采用将输入数据当作字符串的技巧,直接将两个数字以字符串的形式保存起来,再依次遍历这个字符串,通过字符与字符'0'的ASCII值的差,计算字符所表示的数字值,从而完成数字的拆解。
#include<stdio.h>
int main()
{
char a[11],b[11];
while(scanf("%s%s",a,b)!=EOF)//利用字符串将两个数字输入,作为字符串保存在内存中
{
int ans=0; //累加变量
for(int i=0;a[i]!=0;i++) //遍历a中每一个字符,直到a字符串结尾
{
for(int j=0;b[j]!=0;j++)//遍历b中每一个字符,直到b字符串结尾
{
ans+=(a[i]-'0')*(b[j]-'0');
//计算a,b中每个字符所代表的数字两两乘积的和
}
}
printf("%d\n",ans); //输出答案
}
return 0;
}