素数を見つける(2019 Lanqiao Cup Provincial Tournament Group B Simulation Tournament 1を数える)

トピック

  	一天蒜头君猜想,是不是所有的偶数(除了 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;
}

おすすめ

転載: blog.csdn.net/laysan/article/details/113577455