每日刷题(四十四)
蓝桥杯第九届C语言B组省赛习题
习题C:乘积尾零
这个题我的思路是把数字放到数组里进行运算。因为这些数字的乘积肯定比231-1要大,之前我也有一篇博文是关于把超大的数放到数组里去运算的题——蓝桥杯基础练习超全习题题解VIP版——BASIC-30 阶乘计算(用数组进行超出计算机整数表示范围的整数运算)
因为数据里面的数字最大位数是四位数,而如果按顺序遍历第一个数就是四位数,所以不需要特地换个顺序,幸好这里没挖坑
这个题就相当于阶乘计算的变式题,首先设定一个二维数组b用来存放10x10的数字集,然后再把b[0][0]放入a数组中,我这个a数组的思路是从下标0开始存放一个数的个位,下标1存放数的十位,以此类推,到时候输出a数组的时候我就要从89999下标逆向输出。
当我们初始化了a数组(即把b[0][0]放入a数组中),我们就可以开始做乘积运算了。
做三层循环,第一二层是遍历数组b的,当然不能让b[0][0]再次参与运算,所以我们要continue一下,接下来到了核心的步骤了。定义m、t,m用来存放当前乘积后进位的值,t用来存放之前一个数乘积后给现在这个数的值。所以我们对a数组进行遍历,从个位开始依次进行乘法运算,在这层循环下,m = a[tc] * b[i][j] / 10; a[tc] = a[tc] * b[i][j] % 10;是对乘积进行粗略的处理,如果a[tc] + t >= 10,比方说25 * 8 中,8 乘以2时进位1,十位为6,又因为之前8*5进位4,然后又进位了,那么就是这种情况,不容忽视!
核心代码:
s = a[tc] + t;
t = m + s / 10;
a[tc] = s % 10;
否则就是正常情况,a[tc] += t; t= m;
详细C代码如下:
#include<stdio.h>
int main()
{
int a[90000] = {0};
int cn, ct;
int b[10][10] = {0};
for(cn = 0; cn < 10; cn++)
{
for(ct = 0; ct < 10; ct++)
{
scanf("%d", &b[cn][ct]);
}
}
int i = 0, j;
int u = b[0][0], v = u;
while(u)
{
v %= 10;
u /= 10;
a[i++] = v;
v = u;
}
int tc = 0;
int s = 0;
for(i = 0; i < 10; i++)
{
for(j = 0; j < 10; j++)
{
if(i == 0 && j == 0)
continue;
int m = 0;
int t = 0;
for(tc = 0; tc < 90000; tc++)
{
m = a[tc] * b[i][j] / 10; //进位
a[tc] = a[tc] * b[i][j] % 10;
if(a[tc] + t >= 10)
{
s = a[tc] + t;
t = m + s / 10;
a[tc] = s % 10;
}
else
{
a[tc] += t;
t = m; //保存进位数目
}
}
}
}
int cnt = 0;
for(i = 0; i < 90000; i++)
{
if(a[i] == 0)
cnt++;
if(a[i] != 0)
break;
}
printf("%d\n", cnt);
// int k = 0;
// for(i = 89999; i >= 0; i--)
// {
// if(a[i] != 0)
// k = 1;
// if(k)
// printf("%d",a[i]);
// }
return 0;
}
运行结果如下:
所以末尾零的个数为31
如果题目改一下,要我们求出他们的乘积之和那这个代码也可以把答案算出来