题目
If you reverse the word “emirp” you will have the word “prime”. Thatidea is related with the purpose of this kata: we should select allthe primes that when reversed are a different prime (so palindromic primes should be discarded).
For example: 13, 17 are prime numbers and the reversed respectively are 31, 71 which are also primes, so 13 and 17 are “emirps”. But primes 757, 787, 797 are palindromic primes,meaning that the reversed number is the same as the original, so they are not considered as “emirps” and should be discarded.
Your task:
Create a function that receives one argument n, as an upper limit, and the return the following array:
[number_of_emirps_below_n,largest_emirp_below_n, sum_of_emirps_below_n]
Kata中提出一个“emirps”的概念:一个质数倒转后得到一个不同的质数,这个数叫做“emirp”。
例如:13,17是质数,反转后分别是31,71也是质数,13和17是“emirp”。 但是质数757,787,797是回文质数,这意味着反转的数字与原始数字相同,所以它们不是“emirp”。
题目要求创建一个函数,该函数接收一个参数n作为上限,并返回一个数组:
[number_of_emirps_below_n, largest_emirp_below_n, sum_of_emirps_below_n]
其中包含3个元素分别为:
- emirps的个数
- 最大的emirps
- 所有emirps总和
解题思路先找出范围内所有的质数,然后再去除掉回文质数以及反转后为合数的数。
思路
我们需要两个函数分别用来完成:
- 判断一个数是否为质数。
- 去除掉回文质数以及反转后为合数的数。
算术基本定理:任何一个大于1的 自然数 N,如果N不为 质数 ,那么N可以 唯一 分解成有限个质数的乘积
质数的规律:
- 有限多个质数的乘积 一定是一个合数
- 所有大于3的质数都是6X+1或者6X-1的形式,也就是6的倍数的相邻的数,但
并不是所有6X+1或者6X-1都是质数
。
将数字都表示为 6x-1、6x、6x+1、6x+2、6x+3、6x+4 (x为正整数)的形式:
6x-1
6x => 2*3x
6x+1
6x+2 => 2(3x+1)
6x+3 => 3(2x+1)
6x+4 => 2(3x+2)
可证明这些肯定不为质数,即质数只能为6x-1或者6x-1。
代码
//质数判断
bool IsPrime(int n) {
if (n == 2 || n == 3) {
return true; //2、3单独处理
}
if (n % 6 != 1 && n % 6 != 5) {
return false; //非6x-1或6x+1
}
for (int i = 5; i <= sqrt(n); i += 6) {
if (n % i == 0 || n % (i + 2) == 0) {
return false;
}
}
return true;
}
//数字反转
int reverse(int n) {
int rn=0,rem;
while (n != 0) {
rem = n % 10;
rn = rn * 10 + rem;
n /= 10;
}
return rn;
}
//去除掉回文质数以及反转后为合数的数
bool EmirpNum(num) {
int reverseNumber = reverse(num);
if (reverseNumber != num && IsPrime(reverseNumber)) {
return true;
}
else {
return false;
}
}
array<int, 3> findEmirp(const int n) {
vector<int> emirp;
int num, largest, sum = 0;
for (int i = 0; i < n; i++) {
if (IsPrime(i) && EmirpNum(i)) {
emirp.push_back(i);
}
}
num = emirp.size();
largest = emirp[num - 1];
sum = accumulate(emirp.begin(), emirp.end(), 0);
return { num,largest,sum };
}