丑数

题目:我们把只包含因子2、3和5的数称作丑数(Ugly Number)。求按从小到大的顺序的第1500个丑数。例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做第一个丑数。

这道题是经典题目,第九届蓝桥杯A组题目就有一道类似的,一会也一同说了,

解析:只含因子2,3,5,的意思也就是不能有其他素数作为因子,例如7,9,11等等,再或者说这个数一直除以2,再一直除以3,再一直除以5,最后结果为1,即为丑数。

第一种方法,从1一直便利,每次都除以2,除3,除5,判断下是否为1,来找到第1500个丑数,但是这样会超时,代码很简单,就不给大家演示了

第二种方法:丑数乘以2,3,5得到的还是丑数,因此我们可以让1乘2,乘3,乘5,得到三个数,从这三个数中,选一个最小的继续乘2,乘3,乘5,以此类推,下面给出代码演示

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
using namespace std;
#define ll long long
priority_queue<ll,vector<ll>, greater<ll> >num;//优先队列,从小到大排序
set<ll>n;//容器存储,每个数只能存一次,因此可以排除那些重复的丑数,例如3*5,5*3
int main()
{
    ll a[3]= {2,3,5};
    ll k,k1,ans=0;
    while(!num.empty())//清空队列
        num.pop();
    n.clear();//清空容器
    num.push(1);//把第一个丑数存到队列和容器中
    n.insert(1);
    while(ans<1500)//到第1500个丑数时,停止
    {
        k1=num.top();//最小的丑数
        num.pop();
        ans++;
        for(int i=0; i<3; i++)//得到三个新的丑数,判断之前存在不,如果是新的丑数,就把它推到栈 
                              //中和容器中
        {
            k=k1*a[i];
            if(!n.count(k))
            {
                n.insert(k);
                num.push(k);
            }
        }
    }
    printf("%lld\n",k1);
    return 0;
}

第九届蓝桥杯a组第四题
标题:第几个幸运数

到x星球旅行的游客都被发给一个整数,作为游客编号。
x星的国王有个怪癖,他只喜欢数字3,5和7。
国王规定,游客的编号如果只含有因子:3,5,7,就可以获得一份奖品。

我们来看前10个幸运数字是:
3 5 7 9 15 21 25 27 35 45
因而第11个幸运数字是:49

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

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


需要提交的是一个整数,请不要填写任何多余内容。

这道题我不多说了,和上面那道题是一样的思路,上代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
using namespace std;
#define ll long long
priority_queue<ll,vector<ll>, greater<ll> >num;
set<ll>n;
int main()
{
    ll a[3]= {3,5,7};
    ll k,k1=1,ans=-1;//因为题目上说第一位是3,所以减一
    while(!num.empty())
        num.pop();
    n.clear();
    num.push(1);
    n.insert(1);
    while(k1<59084709587505)
    {
        k1=num.top();
        num.pop();
        ans++;
        for(int i=0; i<3; i++)
        {
            k=k1*a[i];
            if(!n.count(k))
            {
                n.insert(k);
                num.push(k);
            }
        }
    }
    printf("%lld\n",ans);
    return 0;
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值