【Code Pratice】—— 乘积尾零、分数、第几个幸运数字

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
    那么可以判断两个数相乘的数中是否可以组成上面两种方式
    具体思路如下:
  1. 遍历每一个数字,并统计其中因子2因子5的个数,因为每一组 2 * 5 就能组成一个0
  2. 因为 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=1qa1(1qn)(q=1)

而本题要求结果为最简式,把首项和公比套入公式的得到最终式子 s n = 2 − ( 1 2 ) n − 1 s_n = 2 - (\frac{1}{2})^{n-1} sn=2(21)n1

逻辑代码

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,也就是说满足条件的幸运数有以下几种

  1. 3的N次方数,或者5的N次方数,或者7的N次方数
  2. X个3 * Y个5 * Z个7 的数 X , Y , Z ∈ ( 0 , ∞ ) X,Y,Z \in(0,\infty) X,Y,Z(0,)

思路如下:

  1. 3开始遍历,直到59084709587505
  2. 判断当前遍历的数是否属于幸运数,属于则计数加一

逻辑代码

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;
}

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ltd Pikashu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值