h0040. 醜い数字

醜い数値とは、素因数が 2、3、または 5 つしかない数値です。シーケンス
1、2、3、4、5、6、8、9、10、12、15、... は、
最初の 11 個の醜い数字を示しています。慣例により、1 が含まれます。
入力の各行には正の整数 n (1≤n≤1500) が与えられ、n 番目の醜い数値の値を見つけるプログラムを作成してください。

入力形式:

入力の各行は正の整数 n (1≤n≤1500) を与え、n=0 で終わります。

出力フォーマット:

入力のセットごとに、行内の n 番目の醜い数値の値を出力します。

入力サンプル:

1
2
5
0

出力例:

1
2
5
// 思路:如果能被2整除就连续除以2,如果能被3整除就连续除以3,如果能被5整除就连续除以5,
//      若最后除下来为1则该数是丑数,先用该方法查找出一定的丑数并且是排好序的,再通过查找出的丑数找出剩余的丑数
// 用丑数查找丑数:按顺序下一个丑数是前面的丑数乘以2、3或5的结果,先分别找出乘以2、3、5的丑数(M2,M3,M5),
//      并找出第一次大于最后一个丑数的M2、M3、M5,即下一个丑数就是取三个中的最小值( min( M2, M3, M5) )
#include<bits/stdc++.h>
using namespace std;
bool check( int x ) //判断是否是丑数
{
    while(x%2 == 0) x/=2; //连续除以2
    while(x%3 == 0) x/=3; //连续除以3
    while(x%5 == 0) x/=5; //连续除以5
    return x == 1; //若为1返回true,否则返回false
}
vector<long long> res;
void find(int x) //查找出下一个丑数
{
    int a2=0, a3=0, a5=0, r;
    while(res[a2]*2 <= x) a2++; //查找出前面的丑数乘以2第一次大于最后一个丑数的位置(丑数的位置)
    while(res[a3]*3 <= x) a3++; //查找出前面的丑数乘以3第一次大于最后一个丑数的位置(丑数的位置)
    while(res[a5]*5 <= x) a5++; //查找出前面的丑数乘以5第一次大于最后一个丑数的位置(丑数的位置)
    r = res[a2]*2<res[a3]*3 ? res[a2]*2:res[a3]*3; //找最小
    r = r<res[a5]*5 ? r:res[a5]*5; //找最小
    res.push_back( r );
}
int n;
int main()
{
    for(int i=1; res.size()<=500; i++) //先找出一些丑数
        if( check( i ) ) //判断是否是丑数
            res.push_back(i);
    while(res.size() <= 1500) find( res.back() ); //将剩下的丑数找出来
    while( cin>>n && n!=0)
        cout << res[n-1] << endl;
    return 0;
}

おすすめ

転載: blog.csdn.net/qq_51936803/article/details/124910579