Goldbach`s予想(LightOJ - 1259)[シンプル] [数論ふるいです]
タグ:講義のトピックにストップを取得
タイトル説明
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 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).
出力
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
サンプル入力
2
6
4
サンプル出力
Case 1: 1
Case 2: 1
注意
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, ...
問題の意味
ゴールドバッハ予想:任意の偶数番号が2以上の2つに分割し、素数の形態で添加することができません。(容疑者は本物の、まだ完全に証明されていません。)
あなたを与える\(nは\)、Q \(N \)解像度のいくつかの方法がありますゴールドバッハの予想に基づいて?\((N \当量1E7) \)
解決
ゴールドバッハの推測を証明することは不可能ですが、データの小さい範囲では、我々は、コンピュータによって解を得ることができます。が、
私たちは、最初の直線ふるいで見つける\(\ 1E7)を超えない範囲内のフル憲法の数(\ 67e4)\ので、それぞれのためにその数ヶ月\(\ n)は、サイクルを再び素数、単に参照するには、\(N \)と素数の数やその品質かどうかの違い。この差は、次いで、素数、もう一つの態様である場合。
ので、我々が\(VIS [1 \ cdots N ] \) アレイとすることができる\(O(1)\)の差が素数要求でないと判断します。
注:この質問は(私はコードがエリクセンスクリーンを持って提出vjudgeを参照)オイラー画面もエリクセン画面を使用することができます使用することができます。
考察内容:素数筛法
コードで
/*
Problem
LightOJ - 1259
Status
Accepted
Time
236ms
Memory
14468kB
Length
798
Lang
C++
Submitted
2019-11-24 22:23:13
Shared
RemoteRunId
1640384*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e7 + 50;
int prime[670000], cnt = 0; //注意这题有内存限制,prime数组开到1e7会RE(MLE).我提前打表看了一下,1e7以内的质数不超过67e4个.
bool vis[MAXN];
void init() //欧拉筛。线性时间复杂度内筛出质数来.prime数组存质数,vis[i]数组判断i是否为质数.
{
vis[1] = 1;
for(int i = 2; i <= int(1e7 + 5); i ++){
if(!vis[i])
prime[++ cnt] = i;
for(int j = 1; j <= cnt && i * prime[j] <= int(1e7 + 5); j ++){
vis[i * prime[j]] = 1;
if(i % prime[j] == 0)
break;
}
}
return ;
}
int main()
{
init();
int T, n, times = 0;
scanf("%d", &T);
while(T --){
scanf("%d", &n);
int ans = 0;
for(int i = 1; i <= cnt && prime[i] <= n / 2; i ++){ //只需循环到n/2即可.在(n/2, n]区间中出现的序偶<a, b>,在[2, n/2]区间也一定出现过.
if(!vis[n - prime[i]]){
ans ++;
}
}
printf("Case %d: %d\n", ++ times, ans);
}
return 0;
}