素数筛笔记
放原题:
对于任何大于或等于4的偶数n,存在至少一对素数p1和p2,使得n = p1 + p2
- 没有人确定这个猜想是否真的成立。然而,对于给定的偶数,可以找到这样的一对素数(如果有的话)。这里的问题是编写一个程序,打印出满足给定偶数的猜想条件的所有素数对数。一个偶数序列作为输入。可以有很多这样的数字。对应于每个数字,程序应输出上述对的数量。请注意,我们只统计不同的数对,因此不应将(p1,p2)和(p2,p1)分别计为两对不同的对。
2的15次方约3万左右,这里如果用一般的方法如
#include <stdio.h> int main(){ int n; for(;;){ scanf("%d",&n); if(n==0)break; int cp=0;//用于记录组数; for(int i=2;i<=n/2;i++)//因为题目说(p1,p2)和(p2,p1)等同,所以判断小于n/2部分的数即可; { int j; int sign=0; for(j=2;j<=i/j;j++) //判断i是否为素数,这里的语句二j<=sqrt(i)和j<=i/2亦可但是用i<=n/i最佳 //因为j<=i/j和j<=sqrt(i)在运行时次数相同但是不用调用sqrt函数,所以会更快一点; { if(i%j==0){sign=1;break;} } if(sign==1)continue; for(j=2;j<=(n-i)/j;j++){ if((n-i)%j==0){sign=1;break;} } if(sign==0)cp++; } printf("%d\n",cp); } }
会出现运行超时的情况,为了进一步缩短运行的耗时,可以先求出所给数据范围中的所有素数并将其存于数组当中,
直接从数组中寻找满足条件素数组,就可以不用进行重复的判断素数的运算了;
所以我们要先得到一份素数表,这里用到埃氏筛法和线性筛法来获得1到4万的素数表:(这里要补充知识:
)
1.埃氏筛法:
#include<stdio.h> #include <stdbool.h> #include<math.h> bool vis[40000]; //false表示是素数,否则不是素数(这里就是定义了一个初始值全部为0的数组 //后面会将下标不是素数的值都改成true(1)) int prime[10000];//存储素数 int cnt = 0;//下标,同时可以计算素数的个数 int main() { int n = 2 << 14;//这里表示2的15次方,亦可写成pow(2,15) for (int i = 2; i <= n; i++) {//判断2到n中的素数 if (!vis[i]) prime[cnt++] = i;//存储素数 for (int j = i + i; j <= n; j += i) { vis[j] = true;//所有素数的倍数都不是素数 }//数组vis[40000]中每一个变量的初始值都为0(false),如果j是某个素数的倍数那么j就一定不是素数,令vis[j] //等于1(true)则可以让false表示是素数,否则不是素数; } int x; while (scanf("%d", &x)) { int cp = 0; if (x == 0) break; for (int i = 0; prime[i] <= x / 2; i++)//直接利用素数表进行判断; if (!vis[x - prime[i]]) cp++; printf("%d\n", cp); } return 0; }