/******************************************************************************* 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; }
作者:shihui512 发表于2013-4-22 11:19:01 原文链接
阅读:78 评论:0 查看评论