您的位置:首页 > 其它

POJ 1338 Ugly Numbers(我的水题之路——丑数2,3,5,质因子组成数)

2012-01-28 23:04 471 查看
Ugly Numbers

Time Limit: 1000MSMemory Limit: 10000K
Total Submissions: 15393Accepted: 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: