给定一个素数集合 S = { p[1],p[2],...,p[k] },大于 1 且素因子都属于 S 的数我们成为丑数(Humble Numbers or Ugly Numbers),记第 n 大的丑数为 h[n]。

算法 1:

  一种最容易想到的方法当然就是从 2 开始一个一个的判断一个数是否为丑数。这种方法的复杂度约为 O( k * h[n]),铁定超时(如果你这样做而没有超时,请跟 tenshi 联系)  

算法 2:

  看来只有一个一个地主动生成丑数了 :

  我最早做这题的时候,用的是一种比较烂的生成方法,复杂度为 O( k * n * log(n) )。

  算法流程如下:

1.初始化最小堆,内置一个元素 1

2.i=0 ,表示求第 i 个丑数(默认 h[0]=1)

3.if i>n then goto 7

4.取出堆中最小的元素 x(如果有多个最小元素,全部取出来), h[i]:= x,i:=i+1

5.把 x*p[1] , x*p[2] ... ,x*p[n] 放入堆中

6.goto 3

7.结束

  这个算法要使用一个最小堆(Heap)的数据结构,。不会超时。

  

算法 3:

  算法2虽然速度还可以,但是算法复杂度还是有点高。这里介绍一下 UsacoGate 提供的标准程序的算法。首先我们知道这样的东西:如果前 m-1 个丑数已经求出来了(包含 0),那么第 m 个数肯定是由前面某个丑数乘 S 里的素数得来的。假设是 h[pindex[i]] 乘 p[i] 而得到 h[m] 的话,把每次乘 p[i] 的 pindex[i] 列出来,肯定是单调的!利用这个,我们可以得到这样的算法:

1.nhum=0 ,表示求第 nhum 个丑数(默认 h[0]=1)

2.令 pindex[i]=0 ,表示一开始无论怎么乘,都是乘 h[0]

3.if (nhum > n ) then goto 7

4.分别求出 h[pindex[i]]*p[i]的值,找出比 h[nhum-1] 大的最小值

5.把这个最小值 h[pindex[minp]]*p[minp] 存入 h[nhum]

6.nhum:=nhum+1;

7.结束

  这个算法复杂度显然为 O( n * k ),已经相当不错了

以上是某个博客的做题心得吧!我把他引用过来仅仅为了介绍丑数的概念

我就以一道例题介绍丑数吧!

description

只有质数2,3,5,7这几个作为因子的数叫做,丑数,比如前20个丑数是(从小到大来说) 1,2,3,4,6,7,8,9,10,12,14,15,16,18,20,21,24,25和27.
							

input

我们给你个n(1<=m<=5842)当输入n为0结束。
							

output

输出第n个丑数。每个数一行。
							

sample_input

1
2
3
4
11

sample_output

1
2
3
4
12


关于丑数的含义在题目中已有解释,有的题目中忽略了“7”这个质因子,其实这都不是最重要的重要的是掌握其处理的方法。
首先,判断一个数是否为丑数的方法如下:
 int find_uglynum(int a)
{
while(a%==)//将这个数中的质因子 2 耗尽
a/=;
while(a%==)
a/=;
while(a%==)
a/=;
while(a/==)
a/=;
if(a==)
return ;
else
return ;
}
但是这种方法过于费时,下面给出该题解题思路:
         首先,第一个丑数为“1”,后面的每一个丑数都是由前一个丑数乘2、3、5或7而来,那么后一个丑数就是前一个乘这四个数得到的最小值,for example:第一个:1,第二个:1*2、1*3、1*5或1*7,显然为2,第三个:2*2,1*3,1*5或1*7,显然是3,第四个:2*2,,2*3,1*5,1*7为4,第五个:3*2,2*3,1*5,1*7……   聪明的你是否看明白了呢?

下面给出本题的代码:
 #include <iostream>
#include <cstdio>
using namespace std;
#define min(a,b) ((a)<(b)?(a):(b))
#define min4(a,b,c,d) min(min(a,b),min(c,d))
int a[];
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout); int n=; int p2,p3,p5,p7;
p2=p3=p5=p7=;
a[]=;
while(n<)//枚举5842个丑数,放在数组a里。
{
a[++n]=min4(*a[p2],*a[p3],*a[p5],*a[p7]);//从现在枚举的4个丑数里,先选择小的放在a里。
if(a[n]==*a[p2])p2++;//如果a[n]==2*a[p2],2*a[p2]可能是吧a[n]枚举出的数,这样p2++,也可能是重复的枚举,这样也是p2++,总之p2++。
if(a[n]==*a[p3])p3++;//同理。
if(a[n]==*a[p5])p5++;//同理。
if(a[n]==*a[p7])p7++;//同理。
}
while(scanf("%d",&n)&&n)
{
printf("%d\n",a[n]);//要谁找谁。
}
return ;
}



Humble Numbers(丑数) 超详解!的更多相关文章

  1. Mysql超详解

    Mysql超详解 一.命令框基本操作及连接Mysql 找到Mysql安装路径,查看版本 同时按快捷键win+R会弹出一个框,在框中输入cmd 点击确定后会出现一个黑框,这是命令框,我们的操作要在这命令 ...

  2. Python3调用C程序(超详解)

    Python3调用C程序(超详解) Python为什么要调用C? 1.要提高代码的运算速度,C比Python快50倍以上 2.对于C语言里很多传统类库,不想用Python重写,想对从内存到文件接口这样 ...

  3. JUC中的AQS底层详细超详解

    摘要:当你使用java实现一个线程同步的对象时,一定会包含一个问题:你该如何保证多个线程访问该对象时,正确地进行阻塞等待,正确地被唤醒? 本文分享自华为云社区<JUC中的AQS底层详细超详解,剖 ...

  4. html5的float属性超详解(display,position, float)(文本流)

    html5的float属性超详解(display,position, float)(文本流) 一.总结 1.文本流: 2.float和绝对定位都不占文本流的位置 3.普通流是默认定位方式,就是依次按照 ...

  5. HTML中DOM核心知识有哪些(带实例超详解)

    HTML中DOM核心知识有哪些(带实例超详解) 一.总结: 1.先取html元素,然后再对他进行操作,取的话可以getElementById等 2.操作的话,可以是innerHtml,value等等 ...

  6. Mybatis案例超详解(上)

    Mybatis案例超详解(上) 前言: 本来是想像之前一样继续跟新Mybatis,但由于种种原因,迟迟没有更新,快开学了,学了一个暑假,博客也更新了不少,我觉得我得缓缓,先整合一些案例练练,等我再成熟 ...

  7. 高斯消元法(Gauss Elimination)【超详解&模板】

    高斯消元法,是线性代数中的一个算法,可用来求解线性方程组,并可以求出矩阵的秩,以及求出可逆方阵的逆矩阵.高斯消元法的原理是:若用初等行变换将增广矩阵 化为 ,则AX = B与CX = D是同解方程组. ...

  8. DES加密 超详解 及 C++编程实现

    参考资料: 1.计算机与软件学院实验报告管理系统资料 2.强烈推荐观看:<信息安全技术>课程微课设计 简介 什么是DES DES全称为Data Encryption Standard,即数 ...

  9. POJ 1659 Frogs' Neighborhood(可图性判定—Havel-Hakimi定理)【超详解】

    Frogs' Neighborhood Time Limit: 5000MS   Memory Limit: 10000K Total Submissions: 9897   Accepted: 41 ...

随机推荐

  1. Java 汉子转拼音

    1. 引入: pinyin4j-1.1.0 包;  http://pan.baidu.com/s/1eQ8a874 2. 转换; private static String ChineseToPiny ...

  2. Linux 下如何安装 JDK ,以 Ubuntu 为例。

    http://www.cnblogs.com/memory4young/p/ubuntu-install-jdk.html 一.下载 首先,当然是要下载了. 地址:http://www.oracle. ...

  3. 利用Selenium和Browsermob批量嗅探下载Bilibili网站视频

    Rerence: http://www.liuhao.me/2016/09/20/selenium_browsermob_sniff_bilibili_video/ 日常生活中,用电脑看视频是非常频繁 ...

  4. python 数组的del ,remove,pop区别

    以a=[1,2,3] 为例,似乎使用del, remove, pop一个元素2 之后 a都是为 [1,3], 如下: >>> a=[1,2,3] >>> a.rem ...

  5. Java的三种代理模式

    Java的三种代理模式 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩 ...

  6. ArcGisServer根据最大最小坐标换算瓦片行列号(转载)

    ArcGisServer根据最大最小坐标换算瓦片行列号 1.前言 在上一节中我们知道了屏幕上一像素等于实际中多少单位长度(米或经纬度)的换算方法,而知道这个原理后,接下来我们要怎么用它呢?它和我们前端 ...

  7. CocoaPods ReactiveCocoa 学习实践一 之 配置环境

    1.安装CocoaPods 1.00.参考 CocoaPods 文档 1.01.是否已安装 which pod 1.1.升级gem命令 sudo gem update --system 1.2.切换C ...

  8. Java经典案例之-“分解质因数”

    /** * 描述:将一个正整数分解质因数.例如:输入90,打印出90=2*3*3*5. * 分析: * 对n进行分解质因数,应该先找到一个最小的质数k,然后按照下列步骤进行: * (1)如果这个质数恰 ...

  9. HTML 5 Web 存储、应用程序缓存、Web Workers

    在客户端存储数据 HTML5 提供了两种在客户端存储数据的新方法: localStorage - 没有时间限制的数据存储 sessionStorage - 针对一个 session 的数据存储 之前, ...

  10. Could not execute auto check for display colors using command /usr/bin/xdpyinfo.(

    Steps to resolve this issue: 1) login into root user( su -l root) 2) execute this command : xhost +S ...