Description
丑数就是这个数的质因子只有2,3,5,7这四个,除此之外不再含有其它 别的质因子。 注意1也被认为是丑数.丑数的前20个为 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, 25, 27, ... ;
Input
每行输入一个N,1 <= N <= 5842,N为0时输入结束.
Output
输出相应的第N个丑数.
题目链接
这道题是有简单的做法,就是用优先队列之类的堆来优化,因为这里的N是比较的小的。所以,直接暴力搞当然是没有问题的,现在来介绍一种级别的强效算法。
我们不妨直接一个个的来确定答案,譬如说,ans[1] = 1这个是必要条件,就像数学归纳法中确定a(1)的做法是一样的。
那么,下一步一定是、、、,选择哪个呢?那么,1之后就有2、3、5、7四种选择,好,很明显的选2,就是由1 * 2得到的,接下去,我们令“”指针指向ans[2],因为它已经和ans[1]做过乘法了。
以此类推,在代码上是这样写到(因为我担心我讲不清楚):
inline void init()
{
ans[1] = 1;
fill(p, p + 4, 1);
ll val;
for(int i=2; i<=maxN; i++)
{
val = MIN_4(ans[p[0]] * 2LL, ans[p[1]] * 3LL, ans[p[2]] * 5LL, ans[p[3]] * 7LL);
if(val == ans[p[0]] * 2LL) p[0]++;
if(val == ans[p[1]] * 3LL) p[1]++;
if(val == ans[p[2]] * 5LL) p[2]++;
if(val == ans[p[3]] * 7LL) p[3]++;
ans[i] = val;
}
}
好了,将答案预处理出来,剩下的就是O(1)的输出了,如下:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <unordered_map>
#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MIN_4(a, b, c, d) min(min(a, b), min(c, d))
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 5842;
ll ans[maxN + 1];
int p[4];
inline void init()
{
ans[1] = 1;
fill(p, p + 4, 1);
ll val;
for(int i=2; i<=maxN; i++)
{
val = MIN_4(ans[p[0]] * 2LL, ans[p[1]] * 3LL, ans[p[2]] * 5LL, ans[p[3]] * 7LL);
if(val == ans[p[0]] * 2LL) p[0]++;
if(val == ans[p[1]] * 3LL) p[1]++;
if(val == ans[p[2]] * 5LL) p[2]++;
if(val == ans[p[3]] * 7LL) p[3]++;
ans[i] = val;
}
}
int main()
{
init();
int x;
while(scanf("%d", &x) && x)
{
printf("%lld\n", ans[x]);
}
return 0;
}