原题链接:https://nanti.jisuanke.com/t/28400
题意:将一个数旋转180°,这个数要是个素数,而且旋转后的数也要是个素数。
180°旋转效果:
0、1、2、5、8这几个数旋转后还是他们本身。
而6旋转会变成9,9旋转后会变成6。
3、4、7这三个数旋转后将不是有效数字。
这里不知道为什么,用atoi(str.c_str())
和reverse()
都不可以。。而且求素数也要用Miller_Rabin(米勒拉宾)。
米勒拉宾求大素数可以看这篇博客
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <ctime>
using namespace std;
typedef long long ll;
ll mult_mod(ll a,ll b,ll Mod) { //快乘法,防止快速幂溢出
ll ans = 0;
while(b) {
if(b&1)
ans = (ans+a)%Mod;
a = a*2%Mod;
b >>= 1;
}
return ans;
}
ll pow_mod(ll a,ll b,ll Mod) { //快速幂
ll ans = 1, base = a;
while(b) {
if(b&1)
ans = mult_mod(ans,base,Mod);
base = mult_mod(base,base,Mod);
b >>= 1;
}
return ans;
}
bool Miller_Rabin(ll n,ll a) { //米勒拉宾素数测试
ll d = n-1, s = 0;
while(!(d&1)) { //求(2^s)*d中的s和d.
d >>= 1;
s ++;
}
ll k = pow_mod(a,d,n);
if(k == 1 )
return true;
for(int j=0; j<s; j++) {
if(k == n-1)
return true;
k = mult_mod(k,k,n); //快乘
}
return false;
}
bool IsPrime(ll n) {
ll a[4] = {3,4,7,11};
for(int i=0; i<4; i++) {
if(n == a[i])
return true;
if(!n%a[i])
return false;
if(n>a[i] && !Miller_Rabin(n,a[i]))
return false;
}
return true;
}
bool check(ll n) {
if(n==2)
return true;
else if(n<2 || !n%2)
return false;
else if(IsPrime(n))
return true;
return false;
}
int main() {
srand(time(NULL));
ll num1,num2,bit;
string str;
cin>>str;
ll len = str.length();
num1 = 0;
bit = 1;
for(ll i=len-1; i>=0; i--) {
num1 += (str[i]-'0') * bit;
bit *= 10;
}
if(!check(num1)) { //判断未翻转前是否是素数
printf("no\n");
return 0;
}
num2 = 0;
bit = 1;
for(ll i=0; i<len; i++) { //翻转
if(str[i] == '3' || str[i] == '4' || str[i] == '7') { //不存在
printf("no\n");
return 0;
}
if(str[i] == '6') {
str[i] = '9';
} else if(str[i] == '9') {
str[i] = '6';
}
num2 += (str[i]-'0') * bit;
bit *= 10;
}
if(!check(num2)) {
printf("no\n");
return 0;
}
printf("yes\n");
return 0;
}