找质数(计蒜客2019蓝桥杯省赛B组模拟赛一)

题目

  	一天蒜头君猜想,是不是所有的偶数(除了 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的两个质数,不妨采用枚举的方法,先枚举出一个质数i,并在表中查找 n - i 是否也为质数,同时满足时则符合要求。

需要注意的是,由于答案可能有多组,所求为字典序最小(即数字最小),所以我们最终输出的案例应当是符合要求时 i 最小的一组用例。

完整代码如下:

#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