Goldbach's conjecture is one of the oldest unsolved problems in number theory and in all of mathematics. It states:
Every even integer, greater than 2, can be expressed as the sum of two primes [1].
Now your task is to check whether this conjecture holds for integers up to 107.
Input
Input starts with an integer T (≤ 300), denoting the number of test cases.
Each case starts with a line containing an integer n (4 ≤ n ≤ 107, n is even).
Output
For each case, print the case number and the number of ways you can express n as sum of two primes. To be more specific, we want to find the number of (a, b) where
1) Both a and b are prime
2) a + b = n
3) a ≤ b
Sample Input
2
6
4
Sample Output
Case 1: 1
Case 2: 1
Note
1. An integer is said to be prime, if it is divisible by exactly two different integers. First few primes are 2, 3, 5, 7, 11, 13, ...
感谢李大超叫我筛选法,呜呜呜uwuwuuwuwuwuwu、
先看素数的三种筛选法:
转载超大神的不加他的链接,就不加。。。
我怂了、、、
原文链接:https://blog.csdn.net/daoshen1314/article/details/100054514
1.最普通的方法不做赘述----按照素数的定义 时间复杂度O(n*n)
public class 普通的方法 {
static final int max=100;
static int prime[]=new int[max];
public static void main(String[] args) {
int k=0;
for(int i=2;i<max;i++){
boolean flag=true;
for(int j=2;j<=Math.sqrt(i);j++)
if(i%j==0)
flag=false;
if(flag) prime[k++]=i;
}
for(int i=0;i<k;i++){
System.out.println(prime[i]);
}
}
}
2.埃拉特斯特尼筛法--当i为素数,i的倍数i*k都不是素数 时间复杂度O(nloglogn)
import java.util.Arrays;
public class 埃拉特斯特尼筛法 {
static final int max=100;
static boolean is_prime[]=new boolean[max];
static int prime[]=new int[max];
public static void main(String[] args) {
Arrays.fill(is_prime, true);
is_prime[0]=is_prime[1]=false;
int k=0;
for(int i=2;i<max;i++){
if(is_prime[i]){
prime[k++]=i;
for(int j=2*i;j<max;j+=i){
is_prime[j]=false;
}
}
}
for(int i=0;i<k;i++){
System.out.println(prime[i]);
}
}
}
3.线性欧拉筛法--每个合数只被它的最小素因子筛选一次 时间复杂度O(n)\
import java.util.Arrays;
public class 线性欧拉筛法 {
static final int max=100000;
static boolean vis[]=new boolean[max];
static int prime[]=new int[max];
public static void main(String[] args) {
Arrays.fill(vis, true);
vis[0]=vis[1]=false;
int k=0;
for(int i=2;i<max;i++){
if(vis[i])
prime[k++]=i;
for(int j=0;j<k&&i*prime[j]<max;j++){
vis[i*prime[j]]=false;
if(i%prime[j]==0){
break;
}
}
}
for(int i=0;i<k;i++){
System.out.println(prime[i]);
}
}
}
vis[i*prime[j]]=false 把prime里记录的素数升序来当作消去合数的最小素因子
if(i%prime[j]==0) break;
当i是prime[j]的倍数时,i=k*prime[j],如果继续进行j+1,i*prime[j+1]=prime[j]*(k*prime[j+1]),
prime[j]是最小素因子,当i=k*prime[j+1]时,会重复,所以break
eg:当i=8,j=0,prime[0]=2,如果不break,i*prime[j+1]=8*3=12*2,也就是说在i=12的时候也会筛这个合数
import java.util.Scanner;
import java.util.Arrays;
public class Main {
static int inf=20000007;
static boolean primes[]=new boolean[inf];
static int p[]=new int[2000005];
static int pn=0;
static void prime(){
pn=0;
Arrays.fill(primes,false);
primes[0]=primes[1]=true;
for(int i=2;i<inf;i++){
if(!primes[i])
p[pn++]=i;
for(int j=0;j<pn&&i*p[j]<inf;j++){
primes[i*p[j]]=true;
if(i%p[j]==0){
break;
}
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner(System.in);
int N=sc.nextInt();
int k=0;
prime();
for(int i=0;i<N;i++){
int n=sc.nextInt();
int ans=0;
for(int j=0;p[j]<=n;j++){
if(primes[n-p[j]]==false&&p[j]<=n-p[j]){
ans++;
}
}
System.out.println("Case "+(i+1)+": "+ans);
}
}
}