华师一附中OI组
标题:
筛法求质数
[打印本页]
作者:
admin
时间:
2019-1-6 20:15
标题:
筛法求质数
筛法求质数的流程:假设求2-100之间的所有质数
1、把2-100之间的所有数写在纸上。(对应编程的做法就是a数组中a(2)-a(100)全部设为1)
2、从2到100,若这个数是质数,那么把它的2倍,3倍,直到不超过100的所有倍数全部刷掉;若不是,则直接跳到下一个数。 用i表是这个数,则刷掉它的倍数可以用类似开关灯的方法来做,两种写法。
3、检查纸上的数字若没有被刷掉,表示是质数,则输出(对应编程的做法就是检查a(2)-a(100),若为1则输出对应的下标)
把上面的解释转换成程序:
1、for (i=2;i<=100;i++) a(i)=1;
2、for (j=i+i;j<=100;j++) a(j)=0;或者for (j=i+1;j<=100;j++) if (j%i==0) a[j]=0; 显然第一种更好。
3、for (i=2;i<=100;i++) if (a(i)==1) cout<<j<<' ';
合成为完整的程序:
#include <iostream>
using namespace std;
const int mn=100;
bool a[mn+5];
int i,j;
int main()
{
for (i=2; i<=mn; i++) a[i]=1;
for (i=2; i<=mn; i++)
if (a[i]==1) for (j=i*2; j<=mn; j+=i) a[j]=0;
for (i=2; i<=mn; i++) if (a[i]==1) cout<<i<<' ';
return 0;
}
复制代码
作者:
admin
时间:
2020-2-11 14:51
象楼上那样做是比较简单清晰的,效率还可以提高,
1、j没有必要从i*2开始,因为i*2可能已经被2刷掉了,i*3可能已经被3刷掉了
2、i的终点没有必要到mn,后面的一些其实早就被刷掉了两者的共同理由是若x=a*b,则x肯定先被a和b中较小数刷掉,那么第一个问题中的j只需要从i*i开始就可以了,第二个问题中的i只需要到sqrt(i)就可以了。
#include <iostream>
using namespace std;
const int mn=100;
bool a[mn+5];
int i,j;
int main()
{
for (i=2; i<=mn; i++) a[i]=1;
for (i=2; i*i<=mn; i++) ///i<=sqrt(mn)
if (a[i]==1) for (j=i*i; j<=mn; j+=i) a[j]=0;
for (i=2; i<=mn; i++) if (a[i]==1) cout<<i<<' ';
return 0;
}
复制代码
欢迎光临 华师一附中OI组 (http://hsyit.cn/)
Powered by Discuz! X3.2