特殊乘法 - 九度教程第39题

特殊乘法 - 九度教程第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。

%运算符求余数的运算可以应用在数位拆解。数位拆解即把一个给定的数字(如3241)各个数位上的数字拆开,即拆成3、2、4、1。

设一个四位数x,该四位数千位为a,百位为b,十位为c,个位为d。那么x满足方程:

x = a * 1000 + b * 100 + c * 10 + d

//只需确定x被10除的余数就能确定其个位上的数字d
x % 10 = ( a * 1000 + b * 100 + c * 10 + d )% 10
x % 10 = a * 1000 % 10 + b * 100 % 10 + c * 10 % 10 + d % 10
x % 10 = d

只需依次将其他数位上的数字移动到个位,然后重复以上过程就可以获得其他数位上的数字。

x / 10 = ( a * 1000 + b * 100 + c * 10 + d) / 10
x / 10 = a * 1000 / 10 + b * 100 / 10  + c * 10 / 10 + d / 10
x / 10 = a * 100 + b * 10 + c

对x做整除,使x除以整数10,即可将十位上的数字移动到个位上,百位上的数字移动到十位数字,其他位依次类推。

#include <stdio.h>

int main()
{
    int a,b;
    while(scanf("%d%d",&a,&b)!=EOF){
        int buf1[11],buf2[11],size1=0,size2=0;
        //用buf1,buf2分别保存从两个整数中拆解出来的数位数字
        //其数量由size1,size2表示
        while(a!=0){//数位拆解,只要当a大于0就不断重复拆解过程
            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;
}

假设输入数据为 0,那么当程序运行到 while循环时,由于被分解整数已经为 0,程序将直接跳过循环,而使数位分解失败。可以在对整数做数位分解之前,对该整数是否为 0 进行特判,若其为 0,则分解结果仅为一个数字 0。

也可以采用将输入数据当做字符串的技巧,直接将两个数字以字符串的形式保存起来,再依次遍历这个字符串,通过字符与字符 '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++){
            for(int j=0;b[j]!=0;j++){
                ans+=(a[i]-'0')*(b[j]-'0');
            }
        }
        printf("%d",ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值