题目大意:
给定一个数和其进制,判断该数和该进制下逆置的数在10进制下是否都是素数,如果是输出Yes
算法思路:
对于输入的每一个数字N,如果是负数退出循环,否则输入进制D,先判断N是否是素数,如果不是就直接输出false并且进行下一次输入,否则就将N在D进制下逆置并且转化为10进制数reversedN
,然后再判断reversedN
是否为素数,如果是输出Yes
,否则输出No
.判断一个数字N是否为素数的方法如下:
方法一:
根据素数的定义可知,素数是指大于1,且只能被1和它自身整除的自然数。1不是素数。根据乘法的特性,可知若从2开始遍历到被判断数的平方根都没有找到能被整除的数,则这个数一定为素数。对应代码如下:
bool isPrime(int N){
if(N<=1) return false;
for (int i = 2; i <= sqrt(N * 1.0); ++i) {
if(N%i==0) return false;
}
return true;
}
方法二:
对于一个大于等于5的素数,其特点是总是等于6x-1
和6x+1
,其中 x 是大于等于1的自然数.那么根据这个特点,得到的结论为,在6的倍数两边的数字不一定是素数,但是不在6的倍数两边的数字一定不是素数,这样就可以优化上面的代码,思路就是首先特判小于4的数字,只有2和3才是素数,然后对于所有对6整除余数不为1和5的说明不在6的倍数的两边,一定不是素数,最后从5开始,步长为6进行遍历每一个在6两边的数字,对于可以对于6的倍数两边的数字可以整除的一定不是素数。代码如下:
bool isPrime(int N){
if(N<=3){
return N>1;//2和3才是素数
}
if(N%6!=1&&N%6!=5) return false;
for (int i = 5; i <= sqrt(N * 1.0); i+=6) {
if(N%i==0||N%(i+2)==0) return false;
}
return true;
}
注意点:
1、如果循环中没有取到根号N测试点3会出错。
2、如果没有对1进行特判,测试点1会出错。
提交结果:
AC代码:
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;
// 将数字N在进制radix下逆置并转化为十进制数
int reverseNWithRadixD(int N,int radix){
if (N==0) return 0;
vector<int> a;
while (N!=0){
a.push_back(N%radix);
N /= radix;
}
int result = 0;
for(int item : a){
result = result*radix+item;
}
return result;
}
// 判断N是否为素数
//bool isPrime(int N){
// if(N<=1) return false;
// for (int i = 2; i <= sqrt(N * 1.0); ++i) {
// if(N%i==0) return false;
// }
// return true;
//}
bool isPrime(int N){
if(N<=3){
return N>1;//2和3才是素数
}
if(N%6!=1&&N%6!=5) return false;
for (int i = 5; i <= sqrt(N * 1.0); i+=6) {
if(N%i==0||N%(i+2)==0) return false;
}
return true;
}
int main(){
int N,D;//十进制数N和进制D
while (true){
scanf("%d",&N);
if(N<0) break;
scanf("%d",&D);
if(!isPrime(N)){
printf("No\n");
continue;
}
int reversedN = reverseNWithRadixD(N,D);
if(isPrime(reversedN)){
printf("Yes\n");
} else {
printf("No\n");
}
}
return 0;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。