问题
丑数是仅有素因子2、3和5的整数。序列1,2,3,4,5,6,8,9,10,12是前十个丑数。1被包含在丑数中。
输入
给出一个正整数n(n<=1500) 输入0表示结束
输出
对于输入的每一行,输出第n个丑数
分析
预先算出第1-1500个丑数存入数组中,从小到大排列,然后取出第n个输出即可。
由于丑数仅有2、3、5这三个因子,所以集合中的元素都是通过乘以2、3、5这三个因子扩展获得的。
比如: ugly[1] =1 ugly[2]=2 ,用第1个丑数 ugly[1]分别以从小到大的顺序乘以2,3两个因子可以得出第2、3个丑数:
ugly[1]*2=ugly[2]=2;
ugly[1]*3 = ugly[3] =3;
由于2*2<1*5
所以第4个丑数:ugly[2]*2=ugly[4]=4
第5个丑数:ugly[1]*5 = ugly[5] = 5;
以此类推,每次2都乘以新的元素,而3和5还乘以原来的元素。
设置三个指针prime2,prime3,prime5分别指向2,3,5待乘的数。然后将三个乘积结果中最小的数加入集合中。
代码
#include "stdafx.h"
#include <iostream>
using namespace std;
const int M = 1501;
int result[M];
//求三个数中的最小值
int min(int a, int b, int c)
{
int min ;
min = a < b ? a : b;
min = min < c ? min : c;
return min;
}
int _tmain(int argc, _TCHAR* argv[])
{
//prime2 prime3 prime5 分别保存质数的计算下标
int prime2 =1, prime3 =1, prime5 = 1;
result[1] = 1; //第一个丑数为1
for (int i = 2; i < M; i++){
//求出当前最小的丑数
result[i] = min(result[prime2] * 2, result[prime3] * 3, result[prime5] * 5);
if (result[i] == result[prime2]*2) prime2++;
if (result[i] == result[prime3]*3) prime3++;
if (result[i] == result[prime5]*5) prime5++;
}
int n;
while (cin >> n){
if (n == 0) break;
cout << result[n] << endl;
}
return 0;
}
测试
时间: 2024-10-05 18:41:11