-1

我正在尝试从在线评审系统中解决一个问题。我有一个可行的解决方案,但效率不够。这是问题所在:

在产品 n = a∙b 中,我们可以想象出最小的数 n,比如 k 种方式?产品 a∙b 和 b∙a 是其中一种方法,其中所有数字都是自然数 (1≤ k ≤50)。

输入一个数字k。输出一个数字 n。

我的代码没有通过四次测试。k=31,37,47太慢了。我一直在想这个问题2天,但没有改善。这是我的代码,如果您有任何想法,请分享。

    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>

    int prime[10000];
    long x,j,i,flag,k,length,p,checker,count,number;

    int main()
    {

    prime[0]=2;
    scanf("%ld",&k);
    //I find prime numbers between 1 and 1000. 1000 can be changed, just for testing

    for (i=3;i<=1000;i=i+2)
            {
            flag=0;
            for (j=2;j<=sqrt(i);j++)
                    {
                    if(i%j==0)
                            {
                            flag=1;
                            break;
                            }
                    }
            if(flag==0)
                    {
                    x++;
                    prime[x]=i;
                    }
            }

    length=x;
    //this loop is too big I know, again for testing. I suspect, there must be a way to make some changes to this for loop 

    for (i=1;i<10000000000;i++)
            {
            number=i;
            p=1;
            for(x=0;x<=length;x++)
                    {
                    if(prime[x]>sqrt(i))
                    break;
                    count=0;
                    while(number%prime[x]==0)
                            {
                            number=number/prime[x];
                            count++;       
                            }
                    p=p*(count+1); 
//I find prime factors of numbers and their powers, then calculate number of divisors

                    }
            //printf("%d\n",p);
            //number of ways is just number of divisors/2 or floor (divisors/2)+1
            if(p%2==0)
            checker=p/2;
            else
            checker=floor(p/2)+1;
            if(checker==k)
                    {
                    printf("%ld\n",i);
                    break;
                    }
            }

    return 0;
    }
4

1 回答 1

1

如果我正确理解了这个问题,它会问你哪个是最小的数 n 正好有 2k 个除数(我应该考虑 1 和 n 吗?)

实际上如果一个数有一个除数a,那么n / a = b是一个整数并且n = a* b(只计算一次a和b,所以你应该除以二除数)

编辑

这样做确实很耗时。所以这就是想法;

对于 n = p1^(a1)*p2^(a2)...pn^(an) 形式的数 n (这是数的素数分解),除数的数是 (a1 + 1)(a2 +1)...(一个+1)

因此,如果您想找到一个具有 k 除数的数,请分解 k。然后将最大的因子分配给最小的素数;例如如果 k = 2*5*7,那么 n 应该是 2^7*3^5*5^2

我知道这不是因为我没有考虑到 (a, b) 等于 (b, a) 但是稍微玩一下它应该可以工作

例子

取 k = 37。然后将数字加倍 - (考虑对称性)。你得到 74。现在,如果你可以想象 n 为 n = n * 1,那么你只需要因式 74(即 2 * 37);然后给 36 到 2 和 1 到 3,前导 n = 2^(36)*3 = 206158430208

如果不能,则需要在之前得到的数字上加 1(在本例中为 74 + 1 = 75 = 25*3);这样你得到 n = 2^24 * 3^2 = 150994944

如果以上都不是,那我可能是错的......

于 2012-12-04T22:10:07.703 回答