ACM中求素数往往涉及到大计算量,很容易就被判TL。
素数筛是一种高效的素数判断方法:比如【2,20】的数可以这样筛选
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
从2开始,把2的倍数筛除
2 3 5 7 9 11 13 15 17 19
先验证一下正确性:
每个合数都能够表示成素数因子的相乘。
经过n轮筛选后,留下的肯定不是前面n个数的倍数,也就是不能表示为比它小的素数连乘表达式,当然该数肯定是素数。
改进:
下次从3开始? 还是从 3 * 3 开始筛3的倍数呢? 答案当然是3 * 3,因为3的1倍、2倍已经被2筛掉了!
bool isnp[MAXN]; // is not prime: 不是素数
void init(int n)
{
for (int i = 2; i * i <= n; i++)
if (!isnp[i])
for (int j = i * i; j <= n; j += i)
isnp[j] = true;
}
以上代码应该是最短的,注意MAXN是最大数,另外false 才是素数。