Ugly Numbers
Time Limit: 1000MS |
|
Memory Limit: 10000K |
Total Submissions: 15393 |
|
Accepted: 6813 |
Description
Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence
1, 2, 3, 4, 5, 6, 8, 9, 10, 12, ...
shows the first 10 ugly numbers. By convention, 1 is included.
Given the integer n,write a program to find and print the n'th ugly number.
Input
Each line of the input contains a postisive integer n (n <= 1500).Input is terminated by a line with n=0.
Output
For each line, output the n’th ugly number .:Don’t deal with the line with n=0.
Sample Input
1
2
9
0
Sample Output
1
2
10
Source
New Zealand 1990 Division I,UVA 136
一种数字叫丑数,它的所有质因子只有2、3、5组成,现在给一个数字i,问,第i个丑数的值是多少
这道题集训的时候做过,但是是用的几个连续并联判断做的,现在用一个循环下标进行优化,看上去更简便,实际上是一样的。
需要做这一题先要分析丑数的性质。丑数分解之后是2、3、5的垒乘,即是说,所有的丑数都是用i个2、j个3、k个5 相乘得到的(i,j,k均为自然数)。那么,对于一个丑数、乘以2、3、5的结果也一定是丑数。所以,我们让2、3、5,都从1开始乘,求出其结果最小的数字,为第二丑数,即为2,由1*2得到,同理得到了3,5均为丑数。但是我们发现4是由2*2得到的,就是说,是由第二个丑数和2相乘得到。
那么我们可以发现,2这个质因数下一次生成丑数的时候,是从第二丑数开始相乘,而不是第一个,则,我们现在定义一个数组at[3],分别表示2、3、5上一次形成丑数的丑数下标,那么我们下一次就可以直接用上一个丑数下标的值去乘以这个质因子,得到一个新的丑数。
所以我们定义另一个数组ugly[1500],用于存储前1500个丑数,所以当前有,ugly[0] = 1, ugly[1] = 2, ugly[2] = 3, ugly[3] = 4,同时定义一个用于存放质因子的数组factor[3] = {2,3,5}。因为我们需要得到第i个丑数,所以在生成丑数的过程中,我们最好让所有的丑数由大到小排列,所以每一次我们都选取一个下一个生成的最小丑数为下一个丑数,比如之前我们已经生成了,1,2,3,4,5,那么我们用三个质因子生成的下一个丑数分别是,ugly[2] * 2,ugly[1] * 3,ugly[1] * 5,计算可知,这三个中最小的下一个丑数为6,可以由ugly[2] * 2,ugly[1]*3得到。
即用minid表示生成的最小丑数为ugly[at[minid]] * factor[minid],即minid为0或1,表示factor中的下标,且同时得到最小的丑数赋值给ugly的下一个下标ugly[top]。
之后,我们更新,三个质因子的下一次更新丑数的位置,将乘积等于ugly[top]的所有下标+1.
运用以上方法,知道找到需要的所有丑数。
代码(1AC):
#include <cstdio>
#include <cstdlib>
#include <cstring>
int at[3];
int factor[3] = {2, 3, 5};
int ugly[1550];
int main(void){
int i, j;
int minid;
int top;
int id;
at[0] = at[1] = at[2] = 0;
ugly[0] = 1;
for (top = 1; top < 1550; top++){
minid = 0;
for (i = 1; i < 3; i++){
if (ugly[at[minid]] * factor[minid] >= ugly[at[i]] * factor[i]){
minid = i;
}
}
ugly[top] = ugly[at[minid]] * factor[minid];
for (i = 0; i < 3; i++){
if (ugly[top] == ugly[at[i]] * factor[i]){
at[i] ++;
}
}
}
while (scanf("%d", &id), id != 0){
printf("%d\n", ugly[id - 1]);
}
return 0;
}