首先题目给出一个定义,一个数具有productive property是指这个数是另一个数所有位上数字的乘积。如2是12各位上数字的乘积,80也是:80=2*2*2*5。
题目要求给出一个正整数i,求出按升序排列后第i个具有productive property的数是多少。题目保证结果不会大于10^18。
最直接的想法就是找出所有这样的数,然后排序,按i输出相应的数。
这里我走了一条弯路,一开始是想找出所有的数,这些数没有大于10的质因子,但这样就要打素数表,还要对一个数进行试除,时间复杂度比较高(从10试到10^18)。
其实反过来想,时间复杂度可以大大降低:这些数的因子只能是2,3,5,7,由这些因子所产生的合数数目肯定大大小于10^18。
简单计算一下可以知道:2^59<10^18, 3^37<10^18, 5^25<10^18, 7^21<10^18。因此只要产生59*37*25*21<=1146075个数就够了。
如何高效产生这些数呢?这里使用了类似DFS+剪枝的技术,设当前这个数为tmp, 则若tmp*c>10^18就不用再乘下去了,其中c是2,3,5,7其中某个数的幂次。具体见程序里的 init
 
 
 #include <iostream>
#include <iostream>
 #include <algorithm>
#include <algorithm>

 using namespace std;
using namespace std;

 __int64 b=1;
__int64 b=1;
 __int64 a[1146075];
__int64 a[1146075];
 __int64 f[4][60];
__int64 f[4][60];
 void init()
void init()


 {
{
 // i,j,k,l分别是2,3,5,7的幂次
    // i,j,k,l分别是2,3,5,7的幂次
 int i,j,k,l,cnt=0;
    int i,j,k,l,cnt=0;
 // 预先计算阶乘
    // 预先计算阶乘
 b=1;
    b=1;
 for(i=1;i<=18;i++) b*=10;
    for(i=1;i<=18;i++) b*=10;
 f[0][0]=f[1][0]=f[2][0]=f[3][0]=1;
    f[0][0]=f[1][0]=f[2][0]=f[3][0]=1;
 for(i=1;i<=59;i++) f[0][i]=f[0][i-1]*2;
    for(i=1;i<=59;i++) f[0][i]=f[0][i-1]*2;
 for(i=1;i<=37;i++) f[1][i]=f[1][i-1]*3;
    for(i=1;i<=37;i++) f[1][i]=f[1][i-1]*3;
 for(i=1;i<=25;i++) f[2][i]=f[2][i-1]*5;
    for(i=1;i<=25;i++) f[2][i]=f[2][i-1]*5;
 for(i=1;i<=21;i++) f[3][i]=f[3][i-1]*7;
    for(i=1;i<=21;i++) f[3][i]=f[3][i-1]*7;
 // 产生所有质因子在10以内的数
    // 产生所有质因子在10以内的数
 __int64 tmp;
    __int64 tmp;

 for(i=0;i<=59;i++)
    for(i=0;i<=59;i++) {
{
 tmp=f[0][i];
        tmp=f[0][i];

 for(j=0;j<=37;j++)
        for(j=0;j<=37;j++) {
{
 if(tmp*f[1][j]>=b) break;
            if(tmp*f[1][j]>=b) break;
 else tmp*=f[1][j];
            else tmp*=f[1][j];

 for(k=0;k<=25;k++)
            for(k=0;k<=25;k++) {
{
 if(tmp*f[2][k]>=b) break;
                if(tmp*f[2][k]>=b) break;
 else tmp*=f[2][k];
                else tmp*=f[2][k];

 for(l=0;l<=21;l++)
                for(l=0;l<=21;l++) {
{
 if(tmp*f[3][l]>=b) break;
                    if(tmp*f[3][l]>=b) break;
 else a[cnt++]=tmp*f[3][l];
                    else a[cnt++]=tmp*f[3][l];
 }
                }
 tmp/=f[2][k];
                tmp/=f[2][k];
 }
            }
 tmp/=f[1][j];
            tmp/=f[1][j];
 }
        }
 tmp/=f[0][i];
        tmp/=f[0][i];
 }
    }
 sort(a,a+cnt);
    sort(a,a+cnt);
 }
}

 int main()
int main()


 {
{
 init();
    init();
 int t,i;
    int t,i;
 scanf("%d",&t);
    scanf("%d",&t);

 while(t--)
    while(t--) {
{
 scanf("%d",&i);
        scanf("%d",&i);
 printf("%I64d\n",a[i-1]);
        printf("%I64d\n",a[i-1]);
 }
    }
 return 1;
    return 1;
 }
}