• 算法-第几个幸运数


    问题描述

    1. 到x星球旅行的游客都被发给一个整数,作为游客编号。
    2. x星的国王有个怪癖,他只喜欢数字3,57
    3. 国王规定,游客的编号如果只含有因子:3,5,7,就可以获得一份奖品。
    4. 我们来看前10个幸运数字是:
    5. 3 5 7 9 15 21 25 27 35 45
    6. 因而第11个幸运数字是:49
    7. 小明领到了一个幸运数字 59084709587505,他去领奖的时候,人家要求他准确地说出这是第几个幸运数字,否则领不到奖品。
    8. 请你帮小明计算一下,59084709587505是第几个幸运数字。

    题目解析

    1.暴力法

    枚举3—目标数+check检查是否为3、5、7数字相乘。这道题不能采用这种算法,会严重超时。

    2.Set生成法

    Set集合在C++中是已经排好序的并去重的,因此就很适合这道题。
    初始状态Set={3,5,7},取第一个数3,分别×3、×5、×7得到9、15、21,接着把9、15、21加入到Set中,此时Set={3,5,7,9,15,21},取略大于3的数5分别×3、×5、×7得到15、25、35,再加入到Set中,此时Set={3,5,7,9,15,21,25,35},如此下去…直到Set中再添加任何数都比原数大的时候循环退出,输出Set中元素的个数即为所求。

    初始状态

    3

    5

    7

    Set

    cycle one

    3

    5

    7

    9

    15

    21

    3分别乘以3、5、7并加入到Set集合中

    cycle two

    3

    5

    7

    9

    15

    21

    25

    35

    5分别乘以3、5、7并加入到Set集合中

    C++代码

    暴力法代码

    1. #include<bits/stdc++.h>
    2. using namespace std;
    3. typedef long long LL;
    4. const LL MAX = 49; //本题中的数带进去计算需16小时
    5. int main()
    6. {
    7. LL ans = 0;
    8. for(int i=3;i<=MAX;i++)
    9. {
    10. int x = i;
    11. while(x%3==0) x/=3; //x可以被3整除
    12. while(x%5==0) x/=5; //x可以被5整除
    13. while(x%7==0) x/=7; //x可以被7整除
    14. if(x==1) ans++;
    15. }
    16. cout<<ans<<endl;
    17. }

    Set生成法代码

    1. #include<bits/stdc++.h>
    2. using namespace std;
    3. typedef long long LL;
    4. const LL MAX = 59084709587505; //本题中的数
    5. int main()
    6. {
    7. int a[3]={3,5,7};
    8. LL t = 1;
    9. set<LL> s; //set集合排序加去重
    10. while(1)
    11. {
    12. for(int i=0;i<3;i++) //生成数
    13. {
    14. LL tt = t * a[i];
    15. if(tt<=MAX) s.insert(tt);
    16. }
    17. t = *(s.upper_bound(t)); //找出s中略大于t的数赋值给t
    18. if(t>=MAX) break; //结束循环
    19. }
    20. cout<<s.size()<<endl;
    21. }

    正确答案

    在这里插入图片描述


    练习题:

    到x星球旅行的游客都被发给一个整数,作为游客编号。

    x星的国王有个怪癖,他只喜欢数字3,5和7。

    国王规定,游客的编号如果只含有因子:3,5,7,就可以获得一份奖品。

    我们来看前10个幸运数字是:

    3 5 7 9 15 21 25 27 35 45  

    因而第11个幸运数字是:49

    小明领到了一个幸运数字 59084709587505,他去领奖的时候,人家要求他准确地说出这是第几个幸运数字,否则领不到奖品。

    请你帮小明计算一下,59084709587505是第几个幸运数字。

    以下选项错误的是?

    A

    typedef long long LL;
    const LL MAX = 59084709587505;
    int main()
    {
        int a[3] = {3, 5, 7};
        LL tou = 1;
        set s;
        while (true)
        {

            for (int i = 0; i < 3; i++)
            {
                LL tt = tou * a[i];
                if (tt <= MAX)
                    s.insert(tt);
            }
            tou = s.upper_bound(tou);
            if (tou >= MAX)
                break;
        }
        cout << s.size() << endl;
        return 0;
    }

    B#define LL long long
    LL maxs = 59084709587505;
    set q;
    int main()
    {
        q.insert(3);
        q.insert(5);
        q.insert(7);
        set::iterator it;
        it = q.begin();
        LL mid;
        while (*it <= maxs)
        {
            mid = *it;
            q.insert(mid * 3);
            q.insert(mid * 5);
            q.insert(mid * 7);
            it++;
        }
        int num = 0;
        for (it = q.begin(); it != q.end(); it++)
        {
            if (*it <= maxs)
                num++;
        }
        cout << num;
        return 0;
    }
    C

    typedef long long LL;
    const LL Max = 59084709587505;
    int a[3] = {3, 5, 7};

    void Find(LL Max)
    {
        set se;
        LL t = 1;
        while (1)
        {
            for (int i = 0; i < 3; ++i)
            {
                LL tt = t * a[i];
                if (tt <= Max)
                    se.insert(tt);
            }
            t = *se.upper_bound(t);
            if (t == Max)
                break;
        }
        cout << se.size() << endl;
    }
    int main(void)
    {

        Find(Max);

        return 0;
    }

    Dint main()
    {
        set st;
        priority_queue, greater> pq;
        const int ok[3] = {3, 5, 7};
        st.insert(1);
        pq.push(1);
        int times = 0;
        while (true)
        {
            long long lucky = pq.top();
            pq.pop();
            if (lucky == 59084709587505)
            {
                cout << times << endl;
                return 0;
            }
            times++;
            for (int i = 0; i < 3; i++)
            {
                long long b = lucky * ok[i];
                if (!st.count(b))
                {
                    st.insert(b);
                    pq.push(b);
                }
            }
        }
        return 0;
    }

    答案:

    1. typedef long long LL;
    2. const LL MAX = 59084709587505;
    3. int main()
    4. {
    5. int a[3] = {3, 5, 7};
    6. LL tou = 1;
    7. set<LL> s;
    8. while (true)
    9. {
    10. for (int i = 0; i < 3; i++)
    11. {
    12. LL tt = tou * a[i];
    13. if (tt <= MAX)
    14. s.insert(tt);
    15. }
    16. tou = s.upper_bound(tou);
    17. if (tou >= MAX)
    18. break;
    19. }
    20. cout << s.size() << endl;
    21. return 0;
    22. }

  • 相关阅读:
    pyhton 类动态绑定函数
    22.支持向量机—高斯核函数
    docker 安装 elasticsearch 7.3.0
    【MySQL】MySQL增删改查与常见陷阱(MySQL专栏启动)
    axs火爆,还有哪些打金游戏(上)
    windows系统安装php,运行php
    基于Springboot的就业服务平台
    redis-设置从节点
    【pytest】 allure 生成报告
    MybatisPlus性能分析与条件构造器wrapper
  • 原文地址:https://blog.csdn.net/mooczhimahu/article/details/126555047