187 Semiprimes
一个合数可以分解成至少两个质数的乘积,很多合数只能分解成两个质数的乘积,比如 ,小于 次方的数字中,有多少个能分解成两个质数相乘?9 和 10 就是满足题意的,而 就是不满足题意的。
分解质因数是比较复杂的,但是给两个质数,得到乘积,看是否小于 MAX
还是很简单的。
进一步,我们没必要用两层 for
循环得到所有满足题意的数,只要知道有几个就可以了。
比如我们有一个质数 ,得到比 MAX/p
小的质数的个数就可以了。
先生成一个系列的质数,二分查找得到 MAX/p
所在的位置即可。
public static long GetAnswer()
{
var primes = Utils.GenPrimes(MAX / 2);
long count = 0;
foreach (var p in primes)
{
long m = MAX / p;
int index = Array.BinarySearch(primes, m);
if (index >= 0)
{
count += index + 1;
}
else
{
count += ~index;
}
}
count += ~Array.BinarySearch(primes, (long)Math.Sqrt(MAX));
return count / 2;
}
foreach
里面计算了 2 次,对于完全平方数,我们只计算了一次,于是乎,再加一次完全平方数的个数,最后统一的除以 2。