关于素数的问题解题报告

对于判断一个数是否是素数,我们的基本思想就是从2。。。。。到这个数之前一个数判断是否整除它的数存在,若存在则表明不是素数,代码如下:

 1 #include<stdio.h>
 2 int main()
 3 {
 4     int i,n;
 5     while(scanf("%d",&n)==1)
 6     {    for(i=2;i<n;i++)
 7              if(n%i==0)    break; 
 8         if(i==n)    printf("YES
");
 9         else           printf("NO
");
10     }
11         return  0;
12 }

但是我们注意到时间复杂度O(n);

我们要观察到其实只要到n的开二次方就行了于是我们优化一下代码:

 1 #include<stdio.h>
 2 #include<math.h>
 3 int main()
 4 {
 5     int i,n;
 6     while(scanf("%d",&n)==1)
 7     {    for(i=2;i<=sqrt(n);i++)
 8              if(n%i==0)    break; 
 9         if(i>sqrt(n))    printf("YES
");
10         else           printf("NO
");
11     }
12         return 0;
13 }
14     

接下来如果是求根给出一个数,求1到这个数的之间所有的素数(⊙o⊙)?

或许基本思路就是用分治思想把它变成一个数是否是素数的问题;

这段代码就不贴出了。

下面介绍今天的主题筛选法:

筛选法的基本思想就是:素数的倍数一定不是素数;

实现方法就是:用一个长度为N+1的数组保存信息(0表示素数,1表示非素数),先假设所有的数都是素数(初始化为0),从第一个素数2开始,把2的倍数都标记为非素数(置为1),一直到大于N;然后进行下一趟,找到2后面的下一个素数3,进行同样的处理,直到最后,数组中依然为0的数即为素数。
说明:整数1特殊处理即可。

下面就贴出代码:

 1 #include<stdio.h>
 2 #include<math.h>
 3 int a[100001];
 4 int main()
 5 {      int i,j,n;
 6 
 7     while(scanf("%d",&n)==1)
 8     {    for(i=2;i<=n;i++)
 9         {if(a[i]==0)
10         for(j=i+i;j<=n;j+=i)
11             a[j]=1; }
12         printf("2");
13         for(i=3;i<=n;i++)
14             if(a[i]==0)    printf(" %d",i);  
15         printf("
");
16          }
17     return 0; 
18  }

预处理筛选法的其它应用还可见:

HDu 1215:

1215 七夕节
题目大意:求一个数的真因子之和
Sample Input:
2
10
20
Sample Output:
8
22
题目分析:

本题特点同前例题:数据量很大(可达50万),每个数据也不小,同样可达50万。
常见方法:预处理筛法
思考:这个筛法和求素数的筛法细节区别在哪里?
再思考:如果是求一个数的因子的数量,哪里需要变化?
至于代码就自己敲出来<( ̄3 ̄)> 表!

原文地址:https://www.cnblogs.com/Bincoder/p/5065548.html