丑数(Ugly Numbers, UVa 136)

题目描述

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

算法实现

  1. 版本1:错误版本
//#define LOCAL
#include<iostream>
#include<cstdio>
#include<queue>
/*
输出第1500个丑数
*/
using namespace std;
typedef long long LL;
const int coeff[3]={2,3,5};
int main(){
#ifdef LOCAL
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
#endif priority_queue<LL,vector<LL>,greater<LL> > pq;//!1
pq.push(1);//初始化得有1个1.
for(int i=1;;i++){
//每次循环都从pq中取出一个丑数,根据这个丑数计算出新的丑数,并注入。
LL ugly=pq.top();
pq.pop();
if(i==1500){cout<<ugly;break;}
else{
//通过这个取出的丑数,计算新的丑数,并入队
for(int i=0;i<3;i++){
LL x=ugly*coeff[i];
pq.push(x);
}
}
}
}

以上思路是通过每次从优先队列pq中获取一个丑数,然后通过这个丑数计算出新的丑数,对于任意的丑数x,他的2,3,5倍也都是丑数,通过这样的方法,可以把所有的丑数一网打尽。

但是这个地方没有考虑周全的是,不同的生成方法可能会生成同一个丑数,所以里面肯定有许多次重复了,比如235=325=532=...,所以需要一个数据结构来记录丑数是不是已经出现过了,set集合挺适合的,那么修改代码后如下。

//#define LOCAL
#include<iostream>
#include<cstdio>
#include<queue>
#include<set>
/*
输出第1500个丑数
*/
using namespace std;
typedef long long LL;
const int coeff[3]={2,3,5};
int main(){
#ifdef LOCAL
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
#endif priority_queue<LL,vector<LL>,greater<LL> > pq;//!1
set<LL> s;
pq.push(1);//初始化得有1个1.
s.insert(1);
for(int i=1;;i++){
//每次循环都从pq中取出一个丑数,根据这个丑数计算出新的丑数,并注入。
LL ugly=pq.top();
pq.pop();
if(i==1500){cout<<ugly;break;}
else{
//通过这个取出的丑数,计算新的丑数,并入队
for(int i=0;i<3;i++){
LL x=ugly*coeff[i];
if(!s.count(x)){
s.insert(x);
pq.push(x);
}
}
}
}
return 0;
}

最新文章

  1. PowerGUI错误-Microsoft SharePoint is not supported with version 4 of the Microsoft .Net Runtime
  2. 为什么 NSLog 不支持 Swift 对象(转)
  3. 原创centos7安装hadoop2.7(转载请注明出处)
  4. P1018 乘积最大
  5. 使用nodejs引用socket.io做聊天室
  6. Japan
  7. linux入门教程(二) 图形界面还是命令窗口
  8. hdu 1394 树状数组
  9. VisualStudio2013Preview对C++11的支持(转载)
  10. Python函数小结(2)-- 装饰器、 lambda
  11. python----slots属性安全类
  12. C++设计模式之装饰者模式
  13. TCP/IP笔记(五)IP协议相关技术
  14. Ubuntu 14.04下Redis安装报错:“You need tcl 8.5 or newer in order to run the Redis test”问题解决
  15. file_get_contents(&quot;php://input&quot;)的使用方法
  16. if判断 -z -n 参数
  17. 关于CC的完全非线性椭圆方程一书的一些小结
  18. 安装好ubuntu 18.10之后,屏幕一直在自动旋转,怎么办?
  19. 如何让自己的Dev C++用上C++11,c++14标准
  20. ACM笔记

热门文章

  1. go的编译与重启
  2. 使用electron构建跨平台Node.js桌面应用
  3. UNIX/Linux系统管理技术手册(2)----bash脚本编程
  4. 扩展javascript原生对象
  5. ubuntu桌面便签 sticky note, xpad
  6. January 28 2017 Week 4 Saturday
  7. sublime text html5开发学习 插件篇记录
  8. ECharts属性设置
  9. 在一个jsp页面中引用另一个jsp文件的路径的问题
  10. PHP中使用substr()截取字符串出现中文乱码问题该怎么办