题目链接: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;
}
如有哪有不足或更好的解决方法,请慷慨提出,感激不尽!!!