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)。 (还不会想出后再来)