Humble Numbers

Humble Numbers

For a given set of K prime numbers S = {p1, p2, ..., pK}, consider the set of all numbers whose prime factors are a subset of S. This set contains, for example, p1, p1p2, p1p1, and p1p2p3 (among others). This is the set of `humble numbers' for the input set S. Note: The number 1 is explicitly declared not to be a humble number.

Your job is to find the Nth humble number for a given set S. Long integers (signed 32-bit) will be adequate for all solutions.

PROGRAM NAME: humble

INPUT FORMAT

Line 1: Two space separated integers: K and N, 1 <= K <=100 and 1 <= N <= 100,000.
Line 2: K space separated positive integers that comprise the set S.

SAMPLE INPUT (file humble.in)

4 19 2 3 5 7

OUTPUT FORMAT

The Nth humble number from set S printed alone on a line.

SAMPLE OUTPUT (file humble.out)

27 
翻译
描述
对于一给定的素数集合 S = {p1, p2, ..., pK}, 来考虑正整数集合中哪些数的质因数全部属于S。这个正整数集合包括,p1, p1p2, p1p1 和 p1p2p3 ....(还有其它)。这是个对于一个输入的S集合的丑数集合。 
注意:我们不认为1 是一个丑数。 
你的工作是对于输入的集合S去寻找集合中的第N个丑数。longint(signed 32-bit)对于程序是足够的。 
PROGRAM NAME: humble 
INPUT FORMAT
(file humble.in) 
第 1 行: 二个被空格分开的整数:K 和 N , 1<= K<=100 , 1<= N<=100,000. 
第 2 行: K 个被空格分开的整数:集合S的元素 
OUTPUT FORMAT
(file humble.out) 
单独的一行,写上对于输入的S的第N个丑数。

SAMPLE INPUT

4 19 2 3 5 7

SAMPLE OUTPUT

27

在集合里面选任意次数的任意数字相乘。排序后,找到第n大的数即是answer了。
But这是不可取的。因为会有太多浪费。也会TLE。比如会有很多很多的重复丑数。但实际上只算作一个丑数。
所以考虑怎么不重复的找到第n大。

So,我们考虑一下递推。
现在已知前m-1个丑数,要递推第m个。HOW?
我们依次枚举集合中的素数,对于每一个素数。
选择一个最小的某丑数,使得 素数*某丑数>第m-1个丑数。
在所有的 {素数*某丑数}这个集合中,最小的那一个就是第m个丑数了。

考虑优化。每一个素数所乘的那个 某素数 一定是递增的。(自行想象即可)所以对于每个素数存一个下标,表示 该下标的丑数 可能就是那个 某丑数。
如果不符合判断条件。下标++ 即可。因为 维护的丑数表也是递增的。

well,所有重点就是这些了。

/*
ID:Andy Chen
LANG: C++
TASK: humble
*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdio>
#define MAXN 100001
#define MAXM 101
using namespace std;
int a[MAXM],p[MAXN],d[MAXN];
int main()
{
    freopen("humble.in","r",stdin);
    freopen("humble.out","w",stdout);
    int n,m,i,j,k,Min;
    while(scanf("%d %d",&m,&n)==2)
    {
        for(i=0;i<m;i++) scanf("%d",&a[i]);
        d[0]=1;
        memset(p,0,sizeof(p));
        for(i=1;i<=n;i++)
        {
            Min=0x7fffffff;
            for(j=0;j<m;j++)
            {
                while(a[j]*d[p[j]]<=d[i-1]) p[j]++;
                if(a[j]*d[p[j]]<Min)
                {
                    Min=a[j]*d[p[j]];
                    k=j;
                }
            }
            d[i]=Min;p[k]++;
        }
        printf("%d\n",d[n]);
    }
    return 0;
}

 



你可能感兴趣的:(Humble Numbers)