トピック
一天蒜头君猜想,是不是所有的偶数(除了 22),都可以用两个质数相加得到呢?于是聪明的蒜头君就找你来验证了。
输入格式
第一行输入一个整数 t 表示测试组数。
接下来 t 行,每行一个整数 n。
输出格式
输出两个整数,因为答案可能有多个,所有要求输出的这两个整数是所有答案中字典序最小的。
数据范围
对于 30% 的数据 1 ≤ t ≤ 10^3。
对于 60% 的数据 1 ≤ t ≤ 10^5。
对于 100% 的数据 1 ≤ 10^6, 4 ≤ n ≤ 10^6 ,n 为偶数。
样例输入
3
4
8
20
样例输出
2 2
3 5
3 17
この質問のデータは大きいため、素数の線形スクリーニングの方法を使用してそれらをテーブルに格納し、最後にテーブルを検索することを検討できます。
計量と預け入れのコードは次のとおりです。
void data()
{
ms(a),ms(b);
for(int i=1;i<=1e6;i++)
for(int j=i;j<=1e6;j+=i)
a[j]++;
for(int i=1;i<=1e6;i++)
if(a[i]==2){
b[l++]=i;
}
}
質問の要件は、合計がnになる2つの素数を見つけることです。列挙の方法を使用して、最初に素数iを列挙し、niも素数であるかどうか、およびそれらが素数であるかどうかを表で調べます。同時に満たされる、それは主張に適合します。
複数の回答セットが存在する可能性があるため、必要な辞書式順序が最小(つまり、最小数)であることに注意してください。したがって、最終的に出力するケースは、要件。
完全なコードは次のとおりです。
#include <bits/stdc++.h>
#define ms(a) memset(a,0,sizeof(a))
using namespace std;
int a[1000009];
int b[1000009];
int l=0;
void data()
{
ms(a),ms(b);
for(int i=1;i<=1e6;i++)
for(int j=i;j<=1e6;j+=i)
a[j]++;
for(int i=1;i<=1e6;i++)
if(a[i]==2){
b[l++]=i;
}
}
int main()
{
l=0;
data();
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int i=0;
int x,y;
while(i<l&&b[i]<=n)
{
x=b[i];
y=n-x;
if(a[y]==2)
break;
i++;
}
printf("%d %d\n",x,y);
}
return 0;
}