NOJ1167丑陋数&双端队列

描述
“丑陋数”是指那些质因子只包含2,3或5的数(可以都不包含,所以1也是一个“丑陋数”)。数列1,2,3,4,5,6,8,9,10,12,...给出了前十个“丑陋数”。
给出正整数n,请输出第n个“丑陋数”。

输入
每行仅有一个正整数n(n<=1500),输入以“0”结尾。

输出
对于每一个输入的n,输出第n个“丑陋数”,对结尾的“n=0”不用作任何输出。

样例输入
1
2
9
0

样例输出
1
2

10


一开始做这道题时,竟然傻傻的遍历所有的数字并判断其是否为丑陋数,结果自然是提交超时了。于是在网上借鉴了别人的思路,既然丑陋数的质因子只包含2、3或5,那么丑陋数必然也是这三个数的乘积。那么我们就可以从最小的1开始,不断的乘2、3或5得到的必然就是丑陋数。然后在按照从大到小的顺序将数字存储起来以便查询。

方法:1.定义一个存放丑陋数的数组result,以及分别用来乘2、3或5的三个双端队列a、b和c。

2.将存放在result中最大的丑陋数分别乘2、3、5放入双端队列中。

3.比较三个双端队列的队首,把最小的那个存入result中并将最小的那个队首元素pop掉(这也就是运用deque双端队列的原因,只有尾端的vector容器并不适合去除首元素)


#include <iostream>
#include <deque> //双端队列,和vector相比其可以对线性表头进行插入删除
using namespace std;
int min(int a,int b)
{
return a>b?b:a;
}
int _tmain(int argc, _TCHAR* argv[])
{
deque<int> result,a,b,c;
int i=1,r;
result.push_back(1);
while(result.size()<1501)
{
r=result[i-1];//选取结果集中最大的丑陋数去乘2、3或5
a.push_back(r*2);
b.push_back(r*3);
c.push_back(r*5);
int tmp=min(a.front(),b.front());
tmp=min(tmp,c.front());//选取三个队列中最小的丑陋数进入结果集
if(a.front()==tmp)
a.pop_front();//利用deque双端队列将符合条件的数从临时的队列中去除
if(b.front()==tmp)
b.pop_front();
if(c.front()==tmp)
c.pop_front();
result.push_back(tmp);
i++;
}
int n;
while(cin>>n)
{
if(n==0)
break;
cout<<result[n-1]<<endl;
}
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值