我正在尝试找到第n个(n <= 2000000)square free semi prime。我有以下代码可以这样做。
int k = 0;
for(int i = 0; i <= 1000; i++)
{
for(int j = i +1 ; j <= 2500; j++ )
{
semiprimes[k++] = (primes[i]*primes[j]);
}
}
sort(semiprimes,semiprimes+k);
primes[]
是素数列表。
我的问题是,我得到n = 2000000
的不同值,对for循环有不同的限制。有人能说出正确计算这些限制的方法吗?
提前致谢..
答案 0 :(得分:2)
您想要计算第n个第一个半素数无方格数。 “first”表示您必须在特定值下生成所有这些内容。您的方法包括生成大量这些数字,对它们进行排序并提取第n个第一个值。
这可能是一个很好的方法,但您必须生成所有数字。在嵌套循环中有两个不同的限制是错过其中一些限制的好方法(在您的示例中,您不计算应该位于primes[1001]*primes[1002]
中的semiprimes
)。
为了避免这个问题,你必须计算一个正方形中的所有半素数,比如[1,L]*[1,L]
,其中L是你对两个循环的限制。
要确定L,您需要的只是计算。
设N是primes[L-1]*primes[L-1]
下的半素数无方格数。
N = (L * L - L) / 2
L * L是成对乘法的总数。 L是平方数。这有两个除以2得到正确的数字(因为primes[i]*primes[j] = primes[j]*primes[i]
)。
你想选择L使得n <= N.所以对于n = 2000000:
int L = 2001, k = 0;
for(int i = 0; i < L; i++)
{
for(int j = i+1 ; j < L; j++ )
{
semiprimes[k++] = (primes[i]*primes[j]);
}
}
sort(semiprimes,semiprimes+k);
答案 1 :(得分:0)
我不相信通过计算框内所有半参数的方法可以在任何合理的时间内工作。假设我们绘制了前200万个半元素的因子(p,q)。为了使图形更加对称,让我们为(p,q)和(q,p)绘制一个点。该图形不会形成漂亮的矩形区域,而是看起来更像双曲线y = 1 / x。这个双曲线延伸到很远,迭代整个包含这些的矩形将是大量的浪费计算。
您可能要考虑首先解决问题“N下面有多少半数?”然后使用二进制搜索。每个查询都可以在大约sqrt(N)步骤中完成(提示:二进制搜索再次出现)。你需要一个相当大的素数表,当然至少要高达100万,可能更多。虽然这可以通过一些预先计算的任意大的常数因子来减少。