当前位置:编程学习 > C/C++ >>

google面试题目:寻找丑数

[cpp] 
/*******************************************************************************
google面试题目:我们把只包含因子2、3和5的数称作丑数(Ugly Number)。
例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做是第一个丑数。
求按从小到大的顺序的第2012个丑数。
 
分析:假设数组ugly[N]中存放不断产生的丑数,
初始只有一个丑数ugly[0]=1,由此出发,
下一个丑数由因子2,3,5竞争产生,得到ugly[0]*2,
ugly[0]*3, ugly[0]*5, 显然最小的那个数是新的丑数,
所以第2个丑数为ugly[1]=2,开始新一轮的竞争,
由于上一轮竞争中,因子2获胜,这时因子2应该乘以ugly[1]才显得公平,
得到ugly[1]*2,ugly[0]*3,ugly[0]*5,
因子3获胜,ugly[2]=3,同理,下次竞争时因子3应该乘以ugly[1],
即:ugly[1]*2, ugly[1]*3, ugly[0]*5, 因子5获胜,得到ugly[3]=5,
重复这个过程,直到第n个丑数产生。总之:
每次竞争中有一个(也可能是两个)因子胜出,下一次竞争中
胜出的因子就应该加大惩罚!
 
本质就是2 ,3 ,5 的乘积的组合,不过要按照顺序组合,
每次都将2,3,5乘以一个已经是丑数的数,
再比较三者的大小,小的进入数组,然后继续比较;
例如:1是丑数,那么下一个斗劲 2 * 1、3 * 1和5*1,
那么获得的是2,2进入数组,下面比较的是2*2、3*1 和5*1
( 重视因为后面的3*1和5*1的大小并不断定,所以还要持续进行比较)
获得3进入数组,再比较 2 * 2、3 * 2和5*1.
 
************************************************************************/ 
 
#include<cstdio>  
#include<iostream>  
#include<cstdlib>  
using namespace std; 
 
/*the smallest in the three*/ 
int mymin(int a, int b, int c) 

    int temp = (a < b ? a : b); 
    return (temp < c ? temp : c); 

 
int FindUgly(int n) 

    int* ugly = new int[n]; 
    ugly[0] = 1; 
    int index2 = 0; 
    int index3 = 0; 
    int index5 = 0; 
    int index = 1; 
    while (index < n) 
    { 
        int val = mymin(ugly[index2]*2, ugly[index3]*3, ugly[index5]*5); 
        //竞争产生下一个丑数  
        if (val == ugly[index2]*2) 
        //将产生这个丑数的index*向后挪一位;  
            ++index2; 
        if (val == ugly[index3]*3) 
        //这里不能用elseif,因为可能有两个最小值,这时都要挪动;  
            ++index3; 
        if (val == ugly[index5]*5) 
            ++index5; 
        ugly[index++] = val; 
    } 
    int result = ugly[n-1]; //ugly[0] = 1  是第一个丑数  
    delete[] ugly; 
    return result; 

int main() 

    int num=1; 
    cout<<"input the number:"<<endl; 
    cin>>num; 
    cout<<"the "<<(num)<<" th agly number is "<<FindUgly(num); 
    return 0; 
 

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

分析:假设数组ugly[N]中存放不断产生的丑数,
初始只有一个丑数ugly[0]=1,由此出发,
下一个丑数由因子2,3,5竞争产生,得到ugly[0]*2,
ugly[0]*3, ugly[0]*5, 显然最小的那个数是新的丑数,
所以第2个丑数为ugly[1]=2,开始新一轮的竞争,
由于上一轮竞争中,因子2获胜,这时因子2应该乘以ugly[1]才显得公平,
得到ugly[1]*2,ugly[0]*3,ugly[0]*5,
因子3获胜,ugly[2]=3,同理,下次竞争时因子3应该乘以ugly[1],
即:ugly[1]*2, ugly[1]*3, ugly[0]*5, 因子5获胜,得到ugly[3]=5,
重复这个过程,直到第n个丑数产生。总之:
每次竞争中有一个(也可能是两个)因子胜出,下一次竞争中
胜出的因子就应该加大惩罚!

本质就是2 ,3 ,5 的乘积的组合,不过要按照顺序组合,
每次都将2,3,5乘以一个已经是丑数的数,
再比较三者的大小,小的进入数组,然后继续比较;
例如:1是丑数,那么下一个斗劲 2 * 1、3 * 1和5*1,
那么获得的是2,2进入数组,下面比较的是2*2、3*1 和5*1
( 重视因为后面的3*1和5*1的大小并不断定,所以还要持续进行比较)
获得3进入数组,再比较 2 * 2、3 * 2和5*1.

************************************************************************/

#include<cstdio>
#include<iostream>
#include<cstdlib>
using namespace std;

/*the smallest in the three*/
int mymin(int a, int b, int c)
{
    int temp = (a < b ? a : b);
    return (temp < c ? temp : c);
}

int FindUgly(int n)
{
    int* ugly = new int[n];
    ugly[0] = 1;
    int index2 = 0;
    int index3 = 0;
    int index5 = 0;
    int index = 1;
    while (index < n)
    {
        int val = mymin(ugly[index2]*2, ugly[index3]*3, ugly[index5]*5);
        //竞争产生下一个丑数
        if (val == ugly[index2]*2)
        //将产生这个丑数的index*向后挪一位;
            ++index2;
        if (val == ugly[index3]*3)
        //这里不能用elseif,因为可能有两个最小值,这时都要挪动;
            ++index3;
        if (val == ugly[index5]*5)
            ++index5;
        ugly[index++] = val;
    }
    int result = ugly[n-1]; //ugly[0] = 1  是第一个丑数
    delete[] ugly;
    return result;
}
int main()
{
    int num=1;
    cout<<"input the number:"<<endl;
    cin>>num;
    cout<<"the "<<(num)<<" th agly number is "<<FindUgly(num);
    return 0;

}

 

 

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,