K.Upside down primes(求大素数--米勒卡宾算法--Miller_Rabin)


题目链接:https://nanti.jisuanke.com/t/28400

       题意是给一串数字,然后对这串数字进行180度翻转,其中1,2,5,8,0翻转完还是它本身,6翻转完是9,9翻转后是6,3,4,7都无法翻转(直接输出no就好)。如果刚开始输入的数字为素数且最后翻转后的数字也是素数的话就输出yes,否则输出no。

       刚开始我用了6n±1来判断素数发现只过了7组样例,然后不管怎么改最多也就过了8组,后来发现了米勒卡宾算法然后又把代码改成了米勒卡宾判断素数,然后还是只过了8组样例,我用的是atoi函数和reverse函数来对输入的字符串进行操作,后来改成了遍历字符串加上米勒卡宾的方法就过了。下面代码的Miller_Rabin有关的四个函数可以直接拿来当模板直接用。


6n±1高效判素数:

bool Check(int num){
	if(num == 1)return false;
	if(num == 2 || num == 3){
		return true;
	}
	if(num % 6 != 1 && num % 6 != 5){
		return false;
	}
	for(int i = 5; i*i <= num; i += 6){
		if(num % i == 0 || num % (i+2) == 0){
			return false;
		}
	}
	return true;
}


atoi和reverse函数的运用(我觉得没啥问题):

int main()
{
	cin>>str;
	int len = str.length();
	if(str == "1"){
		printf("no\n");
		return 0;
	}
	int flag = 0;
	ll temp = atoi(str.c_str());
	for(int i=0;i<len;i++){
		if(str[i] == '6')str[i] = '9';
		if(str[i] == '9')str[i] = '6';
		if(str[i] == '3' || str[i] == '4' || str[i] == '7'){
			flag = 1;
			break;
		}
	}
	reverse(str.begin(),str.end());
	ll ans = atoi(str.c_str());
	if(flag == 1 || !Check(ans) || !Check(temp)){
		printf("no\n");
	}
	else{
		printf("yes\n");
	}
	return 0;
}

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll unsigned long long
using namespace std;
string str;

ll Mult_mod(ll a,ll b,ll mod){
    a %= mod;
    b %= mod;
    ll ans = 0;
    while(b){
        if(b&1){
            ans = ans + a;
            if(ans >= mod)
                ans = ans - mod;
        }
        a = a<<1;
        if(a >= mod) a = a - mod;
        b = b>>1;
    }
    return ans;
}

ll Pow_mod(ll a,ll b,ll mod){
    ll ans = 1;
    a = a % mod;
    while(b){
        if(b&1){
            ans = Mult_mod(ans,a,mod);
        }
        a = Mult_mod(a,a,mod);
        b = b>>1;
    }
    return ans;
}

bool Check(ll a,ll n,ll x,ll t){
    ll ret = Pow_mod(a,x,n);
    ll last = ret;
    for(int i=1;i<=t;i++){
        ret = Mult_mod(ret,ret,n);
        if(ret == 1 && last != 1 && last != n-1)
            return true;
        last = ret;
    }
    if(ret != 1) return true;
    else return false;
}

bool Miller_Rabin(ll n)
{
    if(n<2)return false;
    if(n==2) return true;
    if((n&1)==0) return false;
    ll x=n-1,t=0;
    while((x&1)==0){x>>=1;t++;}
    for(int i=0;i<20;i++){
        ll a=rand()%(n-1)+1;
        if(Check(a,n,x,t))
            return false;
    }
    return true;
}

int main()
{
	cin>>str;
	ll len = str.length();
	ll temp = 0,bit = 1;
	for(int i=len-1;i>=0;i--){
		temp += (str[i] - '0') * bit;
		bit *= 10;
	}
	if(!Miller_Rabin(temp)){
		printf("no\n");
		return 0;
	}
	temp = 0,bit = 1;
	for(int i=0;i<len;i++){
		if(str[i] == '9'){
			temp += 6 * bit;
			bit *= 10;
			continue;
		}
		if(str[i] == '6'){
			temp += 9 * bit;
			bit *= 10;
			continue;
		}
		if(str[i] == '3' || str[i] == '4' || str[i] == '7'){
			printf("no\n");
			return 0;
		}
		temp += (str[i] - '0') * bit;
		bit *= 10;
	}
	if(!Miller_Rabin(temp)){
		printf("no\n");
	}
	else{
		printf("yes\n");
	}
	return 0;
}



猜你喜欢

转载自blog.csdn.net/charles_zaqdt/article/details/81030449