K. Upside down primes(Miller_Rabin求大素数)

原题链接: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;
}

猜你喜欢

转载自blog.csdn.net/qq_16554583/article/details/81044540
今日推荐