题解 | #查找组成一个偶数最接近的两个素数#
查找组成一个偶数最接近的两个素数
http://www.nowcoder.com/practice/f8538f9ae3f1484fb137789dec6eedb9
题目的主要信息:
任意一个偶数(大于2)都可以由2个素数组成,组成偶数的2个素数有很多种情况,本题目要求输出组成指定偶数的两个素数差值最小的素数对。
方法一:
穷举。首先知道判断素数的方法,素数是指在大于1的自然数中,除了1和它自身外,不能被其他自然数整除的数。判断一个数是否为素数用试除法,用各个数从小到大依次去除a,如果到某一个数正好整除,这个a就可以断定不是质数。
从2开始遍历所有小于n的数字i,如果i和n-i均为素数,判断他们之间的差值是否比min小,如果比min小的话,min更新为i和n-i的差值,即为abs(n-i-i),p更新为i;如果差值比min大,则不发生变化,继续往下遍历。当遍历结束后,p和n-p即为组成当前偶数最接近的两个素数。 具体做法:
#include<iostream>
#include<math.h>
using namespace std;
bool isPrime(int n){//判断是否为素数
for(int i=2;i<n;i++){
if(n%i==0){//找到一个可以整除的数,说明n不是素数
return false;
}
}
return true;
}
int main(){
int n;
while(cin>>n){
int min=n;//暂存最小的素数差值
int p=0;//暂存差值最小的素数
for(int i=2;i<n;i++){//从n/2开始遍历
if(isPrime(i)&&isPrime(n-i)){//如果两个数均为素数则满足条件
if(abs(n-i-i)<min){//更新min值
min=abs(n-i-i);
p=i;
}
}
}
cout<<p<<endl<<n-p<<endl;//输出两个素数
}
return 0;
}
复杂度分析:
- 时间复杂度:,for循环的时间复杂度为,每次判断是否为素数的函数isPrime的时间复杂度为。
- 空间复杂度:,只用了常数空间。
方法二:
对方法一进行优化,组成该偶数的值i和n-i分布在n/2的两侧,越靠近n/2,差值就越小,因此可以从n/2开始遍历,找到第一对组成n的素数就是最接近的素数。同时,如果,那么x和y必定分布在的两侧,因此isPrime可以优化为之需要遍历到,避免后面的重复判断。
具体做法:
#include<iostream>
#include<math.h>
using namespace std;
bool isPrime(int n){//判断是否为素数
for(int i=2;i<=sqrt(n);i++){
if(n%i==0){//找到一个可以整除的数,说明n不是素数
return false;
}
}
return true;
}
int main(){
int n;
while(cin>>n){
for(int i=n/2;i>=0;i--){//从n/2开始遍历
if(isPrime(i)&&isPrime(n-i)){//如果两个数均为素数则满足条件
cout<<i<<endl<<n-i<<endl;
break;
}
}
}
return 0;
}
复杂度分析:
- 时间复杂度:,for循环的时间复杂度为,每次判断是否为素数的函数isPrime的时间复杂度为。
- 空间复杂度:,只用了常数空间。