对于判断一个数是否是素数,我们的基本思想就是从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\n"); 9 else printf("NO\n"); 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\n"); 10 else printf("NO\n"); 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("\n"); 16 } 17 return 0; 18 }
预处理筛选法的其它应用还可见:
HDu 1215:
1215 七夕节
题目大意:求一个数的真因子之和
Sample Input:
2
10
20
Sample Output:
8
22
题目分析:
本题特点同前例题:数据量很大(可达50万),每个数据也不小,同样可达50万。
常见方法:预处理筛法
思考:这个筛法和求素数的筛法细节区别在哪里?
再思考:如果是求一个数的因子的数量,哪里需要变化?
至于代码就自己敲出来<( ̄3 ̄)> 表!
时间: 2024-10-23 19:21:36