蓝桥杯练习题十三 - 第几个幸运数(c++)

简介: 蓝桥杯练习题十三 - 第几个幸运数(c++)

题目如下


到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 a[3] = {3, 5, 7};
void Find(LL Max)
{
    set<LL> 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;
}

B.

int main()
{
    set<long long> st;
    priority_queue<long long, vector<long long>, greater<long long>> 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;
}

C.

#define LL long long
LL maxs = 59084709587505;
set<LL> q;
int main()
{
    q.insert(3);
    q.insert(5);
    q.insert(7);
    set<LL>::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;
}

D.

typedef long long LL;
const LL MAX = 59084709587505;
int main()
{
    int a[3] = {3, 5, 7};
    LL tou = 1;
    set<LL> 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;
}

题目分析


不知道为什么,最近几道题都是鸡蛋里面挑骨头,可能让我们自己写一种解法不是难事,但要在众多的解法中选出错误的大难就很难了,所以这也是我们从小考试不喜欢选错误答案的一个原因吧。ps:错误答案意味着要对四个答案分别进行计算,这运算量瞬间翻了4倍。


和上道题一样,这里不对四个选项进行对错判断,留给看题目的同学们。


从题目可知,小明的幸运数字为59084709587505,所谓幸运数字是公约数因子只包含3,5,7的数字,那么显然,3,5,7就是前三个幸运数,因为数字中因子只包含3,5,7那么我们是不是可以用3,5,7分别对3,5,7进行乘法运算?


oh!我真是个小机灵鬼,这样题目不久迎刃而解了吗?每次运算后用一个index表示第几个数,进行++运算。


那也就是说,对3,5,7进行乘法运算:


第一轮:


先用3乘以3,5,7,得到9,15,21;


再用5乘以3,5,7,得到15,25,35;


后用7乘以3,5,7,得到21,35,49;


第二轮:


先用3乘以9,15,21,得到27,45,63;


再用5乘以9,15,21,得到45,75,105;


后用7乘以9,15,21,得到63,105,147;


第三轮:


先用3乘以27,45,63,得到81,135,189;


再用5乘以27,45,63,得到135,225,315;


后用7乘以27,45,63,得到189,315,441;


......


我们发现里面会有很多重复的数字,是不是不太友好?


这时候我们注意到选项中提供了一个函数:upper_bound


upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。


你也可以直接在括号中写num,题目的选项中就是这么用的, t = *se.upper_bound(t);


这样就在se中得到了3,之后是5,之后是7,之后是9,之后是15,之后是21......,用这些数字分别乘以3,5,7


这样,每次只需用这些数字乘以上一次乘积之后得到的三位数即可。省事了不少。


所以在上面的举例中,应该这么写:


用3乘以3,5,7,得到9,15,21;


用5乘以3,5,7,得到15,25,35;


用7乘以3,5,7,得到21,35,49;


用9乘以3,5,7,得到27,45,63;


用15乘以3,5,7,得到45,75,105;


用21乘以3,5,7,得到63,105,147;


......


总结


所谓万变不离其宗,所有选项都脱离不了这个范畴,按照这个思路,我们不需要去看选项就可以写出正确的代码。对于这种选项的题目,太考验人了,对错也存在于须臾之间,不认真看还真容易被忽略呢。有问题,欢迎评论区留言讨论!

目录
相关文章
|
1月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-985 幸运的店家
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-985 幸运的店家
49 0
|
1月前
|
算法 C++
小唐开始刷蓝桥(五)2016年第七届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(五)2016年第七届C/C++ B组蓝桥杯省赛真题
|
1月前
|
网络安全
蓝桥杯-网络安全-练习题-crypto-rsa
蓝桥杯-网络安全-练习题-crypto-rsa
蓝桥杯-网络安全-练习题-crypto-rsa
|
1月前
|
算法 测试技术 C++
小唐开始刷蓝桥(八)2013年第四届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(八)2013年第四届C/C++ B组蓝桥杯省赛真题
|
1月前
|
算法 C++ 数据格式
小唐开始刷蓝桥(七)2014年第五届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(七)2014年第五届C/C++ B组蓝桥杯省赛真题
|
1月前
|
算法 C++
小唐开始刷蓝桥(六)2015年第六届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(六)2015年第六届C/C++ B组蓝桥杯省赛真题
|
1月前
|
C语言
蓝桥杯练习题
蓝桥杯练习题包括6道C语言编程题:1. 判断三位数是否为水仙花数;2. 输出区间质因数分解;3. 将秒转换为&#39;H:M:S&#39;格式;4. 判断闰年;5. 删除可被整除元素并排序数组,数字转字母;6. 分类比较两个字符串关系。每题涉及不同逻辑操作,适合编程初学者练习。
26 3
|
1月前
|
人工智能 搜索推荐 C++
小唐开始刷蓝桥(一)2020年第十一届C/C++ B组第二场蓝桥杯省赛真题
小唐开始刷蓝桥(一)2020年第十一届C/C++ B组第二场蓝桥杯省赛真题
|
1月前
|
机器学习/深度学习 存储 人工智能
小唐开始刷蓝桥(三)2018年第九届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(三)2018年第九届C/C++ B组蓝桥杯省赛真题
|
1月前
|
存储 人工智能 算法
小唐开始刷蓝桥(四)2017年第八届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(四)2017年第八届C/C++ B组蓝桥杯省赛真题