POJ 1338 Ugly Numbers(我的水题之路——丑数2,3,5,质因子组成数)
2012-01-28 23:04
471 查看
Ugly Numbers
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
Sample Output
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):
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 15393 | Accepted: 6813 |
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; }
相关文章推荐
- POJ1338 Ugly Numbers 丑数 [数论]
- POJ 2591 Set Definition(我的水题之路——又一个丑数)
- poj 1338 Ugly Numbers(丑数模拟)
- POJ 2247 Humble Numble(我的水题之路——丑数2,3,5,7)
- POJ-1338-Ugly Numbers-丑数
- POJ 1338 Ugly Numbers 寻找丑数
- POJ 1338 Ugly Numbers(丑数)
- poj 1338 Ugly Numbers [ 离线预处理 - 只处理丑数,复杂度很低 此题也是 程序猿的经典面试题]
- POJ 1338 Ugly Numbers(丑数)
- poj 1338 Ugly Numbers(丑数模拟)
- POJ 2545+2591+2247+1338简单水题
- Ugly Numbers--POJ 1338
- POJ 2545+2591+2247+1338简单水题
- poj-1338-Ugly Numbers-数论
- poj水题之路(转)
- POJ 1247 Magnificent Meatballs(我的水题之路——数组两边求和)
- POJ-1338-暴力水题
- POJ 1656 Counting Black(我的水题之路——表格涂色)
- POJ 2013 Symmetric Order(我的水题之路——奇偶输出)
- POJ 2578 Keep on Truckin'(我的水题之路——谁先大于168)