哥德巴赫猜想
题目背景
哥德巴赫猜想是世界近代三大数学难题之一。至今还未被成功证明。
题目描述
虽然哥德巴赫猜想尚未被成功证明,但是这个猜想目前在计算机处理能力范围内是成立的。
哥德巴赫猜想可以描述为:任意一个大于2的偶数都可以写成两个质数之和。
因此,你也来设计一个程序,将给定的大于2的偶数a拆分成两个质数之和。(有多种拆分方案时,输出较小的加数相比其他拆分方法最小的方案)
输入格式
第一行一个整数q
接下来的q行,每行一个偶数a
输出格式
q行,每行对应一次询问的答案
样例数据
样例输入1
5
4
6
888
890
892
样例输出1
2 2
3 3
5 883
3 887
5 887
数据范围
对于100%的数据,4≤a≤10^5,1≤q≤10^4
思路:
我是没有什么好办法,因为数据范围只到100000,所以我先把100000以内的质数先全找出来,然后在输入a的时候,遍历所有的质数,判断这个质数是不是a的分解方案(两个质数,加起来等于a)的其中一个数,比如,我们定义一个变量c,c=a-当前遍历到的质数;,如果c是质数,那我们就直接输出(因为我们确定当前遍历到的质数是质数,所以只要判断c就好了)
思路还是很简单的,就是暴力
代码:
#include<bits/stdc++.h>
using namespace std;
int zz(long long a){//判断质数
if(a==1)return 0;
for(int i=2;i<=sqrt(a);i++)
if(a%i==0)return 0;
return 1;
}
int main(){
long long maaa[100000],b[100000],cnt=0,q,a,c;
for(int i=2;i<=100000;i++){//埃式筛法,把100000以内的质数全存在数组b里面
if(maaa[i]==0){
b[++cnt]=i;
for(long long j=2*i;j<=100000;j+=i)
maaa[j]=1;
}
}
cin>>q;//读入
for(int i=1;i<=q;i++){
cin>>a;//读入
for(int i=1;i<=cnt;i++){//一共有cnt个质数,这里就是遍历,找a能分成那两个质数
c=a-b[i];//b[i]为a分成的第一个质数,那c就是a分成的第二个质数
if(zz(c)){//a=b[i]+c,如果c也是质数,那就输出
cout<<b[i]<<" "<<c<<endl;
break;//输出了就不用找了直接结束
}
}
}
return 0;
}
不知道有没有更高效的方法,有人知道吗?
拓展:
不知道什么是埃式筛法的看这里:点我
不会判断质数的看这里(真的有人不会吗):点我