1 | 乘积尾零
题目
如下的10行数据,每行有10个整数,请你求出它们的乘积的末尾有多少个零?
5650 4542 3554 473 946 4114 3871 9073 90 4329
2758 7949 6113 5659 5245 7432 3051 4434 6704 3594
9937 1173 6866 3397 4759 7557 3070 2287 1453 9899
1486 5722 3135 1170 4014 5510 5120 729 2880 9019
2049 698 4582 4346 4427 646 9742 7340 1230 7683
5693 7015 6887 7381 4172 4341 2909 2027 7355 5649
6701 6645 1671 5978 2704 9926 295 3125 3878 6785
2066 4247 4800 1578 6652 4616 1113 6205 3264 2915
3966 5291 2904 1285 2193 1428 2265 8730 9436 7074
689 5510 8243 6114 337 4096 8199 7313 3685 211
思路
刚看到题目,首先想到的就是把乘积进行求余10操作,有几次求余10为0,那就有几个尾零,这个想法很暴力,初想貌似可行,但是有个问题,这些数字的乘积一定会爆掉数据的最大范围,那么这样的思路就存在很大问题了
换个想法,末尾有0,说明这个乘积肯定是10的倍数,而10的由来有两种
2 * 5 = 10
1 * 10 = 10
那么可以判断两个数相乘的数中是否可以组成上面两种方式
具体思路如下:
- 遍历每一个数字,并统计其中
因子2
和因子5
的个数,因为每一组2 * 5
就能组成一个0 - 因为
2 * 5
这个式子共需要两个因子,缺少其中一个都无法得到一个0,所以最终0的个数就是能组成完成2 * 5
式子的个数,也就是因子2
和因子5
中个数最少的那个。
例子
比如 15 * 48 * 20 = 14400
,其中
15 = 3 * 5
48 = 2 * 2 * 2 * 2 * 3
20 = 2 * 2 * 5
三个数字共有因子2
6个,因子5
2个,而这些因子最终只能组成两组完整的2 * 5
,所以答案就是因子5
的个数
逻辑代码
int ProTailZero(int i_uNum)
{
int res = -1;
if (1 > i_uNum)
{
return res;
}
int inNum = 0;
int num5 = 0;
int num2 = 0;
for (int i = 0; i < i_uNum; i++)
{
cout << "Please input num [" << i << "]: ";
cin >> inNum;
while (0 == inNum % 5)
{
num5++;
inNum /= 5;
}
while (0 == inNum % 2)
{
num2++;
inNum /= 2;
}
}
res = num5;
if (num2 < num5)
{
res = num2;
}
return res;
}
2 | 分数
题目
1 / 1 + 1 / 2 + 1 / 4 + 1 / 8 + 1 / 16 1/1 + 1/2 + 1/4 + 1/8 + 1/16 1/1+1/2+1/4+1/8+1/16 ……, 每一项都是前一项的一般,如果一共有20项,求这个和是多少,结果用分数表示出来,类似 3 / 2 3/2 3/2,分母要求互质(即最简式)
思路
这是很典型的数学题 —— 等比数列求和,有题目可知
- 公比 q = 1 2 q = \frac{1}{2} q=21
- 首项 a 1 a_1 a1 = 1
套入求和公式
S
n
=
n
a
1
(
q
=
1
)
S_n = na_1 (q = 1)
Sn=na1(q=1)
S
n
=
a
1
(
1
−
q
n
)
1
−
q
(
q
≠
1
)
S_n = \frac{a_1 (1 - q^n)}{1-q} (q\neq1)
Sn=1−qa1(1−qn)(q=1)
而本题要求结果为最简式,把首项和公比套入公式的得到最终式子 s n = 2 − ( 1 2 ) n − 1 s_n = 2 - (\frac{1}{2})^{n-1} sn=2−(21)n−1
逻辑代码
int Pow(int i_uDigits, int i_uNum)
{
if (1 == i_uDigits)
{
return 1;
}
else if (i_uNum > 0)
{
return i_uDigits * Pow(i_uDigits, i_uNum - 1);
}
else
{
return 1;
}
}
int Fraction(int i_uNum)
{
int res = -1;
if (1 > i_uNum)
{
return res;
}
res = 1;
int Molecular = 1;
int Denominator = 1;
Denominator = Pow(2, i_uNum - 1);
cout << "Denominator = " << Denominator << endl;
Molecular = (2 * Denominator) - 1;
cout << "The sum of the first " << i_uNum << " terms of the isometric series is [" << Molecular << "/" << Denominator << "]." << endl;
return res;
}
3 | 第几个幸运数
题目
到x星球旅行的游客都被发给一个整数,作为游客编号。
x星的国王有个怪癖,他只喜欢数字3,5和7。
国王规定,游客的编号如果只含有因子:3,5,7,就可以获得一份奖品。
我们来看前10个幸运数字是:3 5 7 9 15 21 25 27 35 45
因而第11个幸运数字是:49
小明领到了一个幸运数字 59084709587505
,他去领奖的时候,人家要求他准确地说出这是第几个幸运数字,否则领不到奖品。
请你帮小明计算一下,59084709587505
是第几个幸运数字。
思路
首先确定幸运数的判断规则:只含有因子3,5,7
,也就是说满足条件的幸运数有以下几种
- 3的N次方数,或者5的N次方数,或者7的N次方数
- X个3 * Y个5 * Z个7 的数 X , Y , Z ∈ ( 0 , ∞ ) X,Y,Z \in(0,\infty) X,Y,Z∈(0,∞)
思路如下:
- 从
3
开始遍历,直到59084709587505
- 判断当前遍历的数是否属于幸运数,属于则计数加一
逻辑代码
int LuckyNumber(long long i_u32Num)
{
int res = 0;
if (3 > i_u32Num)
{
return res;
}
res = 1;
for (long long i = 3; i < i_u32Num; i++)
{
long long tmp = i;
while (!(tmp % 3))
{
tmp /= 3;
}
while (!(tmp % 5))
{
tmp /= 5;
}
while (!(tmp % 7))
{
tmp /= 7;
}
if (1 == tmp)
{
res++;
}
}
return res;
}