浙江工商大学oj iSTEP 1051 A × B problem 的 一种c语言解法

题目链接:iSTEP | A × B problem

此为 浙江工商大学oj编程实训参考题库(题号列表)-CSDN博客 的系列的一篇文章。

===================================================================================================

题目 1051 A × B problem 

描述

Redraiment碰到了一个难题,需要请你来帮忙:给你两个整数,请你计算A × B。

输入

数据的第一行是整数T(1 ≤ T ≤ 20),代表测试数据的组数。 接着有T组数据,每组数据只有一行,包括两个非负数A和B。 但A和B非常大,Redraiment能保证这些数用long来保存一定会溢出。 但A和B的位数最大不会超过100位。

输出

对应每组测试数据,你都要输出两行: 第一行为:"Case #:", # 代表这是第几组测试数据。 第二行是一个等式:"A * B = Sum", Sum 代表 A × B 的结果。 你要注意这个等式里包含了几个空格。 要求每组数据之间都需要保留一个空行。

输入样例 1 

2
1 2
123456789 987654321

输出样例 1

Case 1:
1 * 2 = 2

Case 2:
123456789 * 987654321 = 121932631112635269

===================================================================================================

解题挫见:乍一看这道题很easy,其实不然。这道题的难点在于他的数据中有接近100位的数,就连unsigned long long都撑不住(最大十进制20位,而int为十进制10位),所以要换一种存储和计算的方法——数组来存储。

知识点:数据处理

以下为通过代码以及一些详细的注释(为用c语言书写):

!!!!!!!!!!!!!!!仅参考思路,严禁直接ctrl+c!!!!!!!!!!!!!!!

//
// Created by COLORFUL on 2023/10/5.
//
#include "stdio.h"
int t,i,digit_a = 0,digit_b = 0,digit_sum = 0;              //digit_a,digit_b表示a,b的位数


void solve()
{
    int a[105] = {0},b[105] = {0},sum[210] = {0};           //因为a,b不超过100位 那就只能用数组进行存储了

    digit_a = 0,digit_b = 0,digit_sum = 0;                 //及时初始化

    while(++digit_a)                                       //对a进行存储,注意要用++digit_a,先自加1在赋值,不然会直接跳出循环
    {
        char c = getchar();
        if(c == ' ')
        { break;}                                          //判断有没有读到空格,如果读到了那就是整个数被读完了,直接break掉

        a[digit_a] =  c - 48;                              //强制转换后会变成ascll码,所以要-48成正常数字
    }
    digit_a -= 1;                                          //因为读取空格和回车时会加一位,所以要及时去掉

    int digit_r = digit_a;                                 //用途看下面
    int digit_l = 1;

    while(digit_l < digit_r)                              //读取时的下标刚好与计算用的相反。比如1000 读取时a[1] = 1,
    {                                                     //而我们计算时想要的却是a[4] = 1。所以用双指针法(应该算吧)将其倒转
        int reg = a[digit_l];
        a[digit_l] = a[digit_r];
        a[digit_r] = reg;
        ++digit_l;
        --digit_r;
    }

    while(++digit_b)                                       //与上一个相同
    {
        char c = getchar();
        if(c == ' ' ||c == '\n')
        { break;}
        

        b[digit_b] =  c - 48;
    }
    digit_b -= 1;

    digit_r = digit_b;
    digit_l = 1;

    while(digit_l < digit_r)
    {
        int reg = b[digit_l];
        b[digit_l] = b[digit_r];
        b[digit_r] = reg;
        ++digit_l;
        --digit_r;
    }


    for (int j = 1; j <= digit_a; ++j)                   //数组形式的乘法计算
    {
        for (int k = 1; k <= digit_b ; ++k)
        {
            sum[j + k - 1] += a[j] * b[k];
            digit_sum = j + k - 1;
            if(sum[j + k - 1] / 10 != 0)                 //乘法中进位的实现
            {
                sum[j + k] += sum[j + k - 1] / 10;
                sum[j + k - 1] %= 10;
                digit_sum = j + k;
            }

        }
    }

    printf("Case %d:\n",i);                   

    for (int j = digit_a; j >0 ; --j)
    {
        printf("%d",a[j]);
    }

    printf(" * ");

    for (int j = digit_b; j >0 ; --j)
    {
        printf("%d",b[j]);
    }

    printf(" = ");

    int check = digit_sum;
    for (int j = digit_sum; j >0; --j)
    {
        if(sum[check] == 0 && check > 1)
        {
            --check;
            continue;
        }

        printf("%d",sum[j]);
    }

    printf("\n");

    if(t > i){printf("\n");}          //要求每组数据之间都需要保留一个空行。
}


int main()
{
    scanf("%d",&t);              //测试数据组数输入
    getchar();                         //读掉t后面的回车,以防对之后的getchar产生影响

    for (i = 1; i <= t; ++i)           //本来想着用while(t--)的,但题意中要求显示"Case #:",那还是用for更方便
    {
        solve();
    }

    return 0;
}

如有哪有不足或更好的解决方法,请慷慨提出,感激不尽!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值