PAT Basic Level 1007 *


1
#include <stdio.h> 2 #include <math.h> //此题注意判断素数用的方法 3 int main () 4 { 5 int x; 6 scanf("%d",&x); 7 int primeList[10000] = {0}; //数组开的小会提示段错误 8 int flag = 0; 9 int i ; 10 int j = 2; 11 int num = 0; 12 13 for(i=2; i<=x; i++) //判断小于X的所有数字是否为素数,若是则将其放入primeList 14 15 { 16 for(j=2; j<=sqrt(i); j++) 17 { 18 if( i%j==0 ) 19 { 20 break; 21 } 22 } 23 24 25 if( j>sqrt(i) ) 26 primeList[flag++] = i; //这个prime[]是int型,跟下面讲的不同。 27 28 } 29 int p ; 30 int ret = 0; 31 for( p = 0;p < flag -1;p++) //判断相邻两项是否相差2 32 { 33 if(primeList[p+1]-primeList[p] == 2) 34 { 35 ret++; 36 } 37 } 38 printf("%d",ret); 39 return 0 ; 40 }

 反思:此题要注意判断素数的方法,用普通的方法会超出规定运算时间。

1.直接暴力从2开始直接不断判断x能否被其整除。

十分朴素,很明显x除以比自己一半大的数一定不是整数。

此法的时间复杂度为O(n).


 

2.只需观察从2到√n中是否能整除x,若没有则为素数

原理:任何一个数都可以看成是两个数相乘,设a = b * c,   又 a = √a * √a,如果有一个小于√a的数能整除a,能么必然有一个大于√a的数整除a,则a不是素数。

此法时间复杂度O(√n)


 

3.埃拉托色尼素数筛选法

以上的方法只能够判断一个数是否是素数,当需求一定范围内所有素数时就并不适用了。这里介绍筛法求所求者。

简而言之,就是从2开始将所有素数整数倍全部删去,留下的就是素数。

原理:一个数是素数,呢么他的倍数一定不是素数。

 1 #include <stdio.h>
 2 int main ()
 3 {
 4     int primelist[100] = {0};    //标记1则为不是素数
 5     int i;
 6     int j ;
 7     for(i = 2;i < 100;i++)
 8     {
 9         if(primelist[i] == 0)          //如果不是素数就将其倍数全部置1 
10         {
11             for(j = i + i;j < 100;j += i)       //内存循环其实可以优化,不用从i+i开始只需从i * i开始就行了原因是 i + i ~ i * i之间的数必然被i之前的数字筛过了
12             primelist[j] = 1;                    //如 i = 5若用原方法,会冗余计算 10,15,20,其实可以发现 10 = 2 * 5 (被2筛过),10 = 3 * 5(被3筛过)....
13         }    
14     } 
15     for(i = 2;i < 100;i++)
16     {
17         if(primelist[i] == 0)
18         printf("%d ",i);
19     }
20     return 0;
21 } 

此法的时间复杂度为O(n*log log n)。 (还不会想出后再来)

 

posted @ 2016-10-18 22:57  Ponytai1  阅读(186)  评论(0编辑  收藏  举报