題目描述
任意一個偶數(大於2)都可以由2個素數組成,組成偶數的2個素數有很多種情況,本題目要求輸出組成指定偶數的兩個素數差值最小的素數對
輸入描述:
輸入一個偶數
輸出描述:
輸出兩個素數
示例1
輸入
20
輸出
7
13
思路
本題首先需要判斷素數,素數表示除過1和本身,不能被其它數整除。通過循環遍歷來判斷一個數是否爲素數。最近的兩個素數應該從最中間的位置開始向兩邊查找。
解答代碼
#include <iostream>
#include <math.h>
using namespace std;
// 判斷素數
bool IsPrime(int n) {
// 只遍歷到開方出,不能被開方左邊的數整除,則一定不能被開方右邊的數整除
for (int i = 2; i <= sqrt(n); i++) {
if (!(n % i)) {
return false;
}
}
return true;
}
int main() {
int num;
while (cin >> num) {
int p1, p2;
p1 = p2 = num / 2;
while ( p1 > 0, p2 <= num) {
// 先找到p1爲素數,再找p2,最後判斷p1與p2相加是否爲num
if (IsPrime(p1)) {
if (IsPrime(p2)) {
if (p1 + p2 == num) {
break;
}
else if (p1 + p2 > num) {
--p1;
}
else if (p1 + p2 < num) {
++p2;
}
}
else {
++p2;
}
}
else {
--p1;
}
}
cout << p1 << endl << p2 << endl;
}
return 0;
}
代碼優化:
兩個素數相加爲原來的偶數,既然是從中間開始找,那麼一個數相加多少,另外一個數必然會減去多少,只有這樣兩個數加起來纔會等於原來的偶數。(不存在一個多加,另一個少減,這樣加起來肯定不會等於原來的偶數)
#include <iostream>
#include <math.h>
using namespace std;
// 判斷素數
bool IsPrime(int n) {
// 只遍歷到開方出,不能被開方左邊的數整除,則一定不能被開方右邊的數整除
for (int i = 2; i <= sqrt(n); i++) {
if (!(n % i)) {
return false;
}
}
return true;
}
int main() {
int num, i;
while (cin >> num)
{
//從中間向兩邊找
for (i = num / 2; i > 0; i--)
{
if (IsPrime(i) && IsPrime(num - i))
break;
}
cout << i << endl << num - i << endl;
}
return 0;
}