Project Euler 41 Pandigital prime( 米勒测试 + 生成全排列 )


题意:如果一个n位数恰好使用了1至n每个数字各一次,我们就称其为全数字的。例如,2143就是一个4位全数字数,同时它恰好也是一个素数。

最大的全数字的素数是多少?

思路:

  1. 最大全排列素数可以从 n = 9 使用 perv_permutation 倒序生成。
  2. 当 n = 9 或者 n = 8 时生成的全排列构成的数一定不是素数,因为它一定能被 3 整除,所以从 7 开始枚举。
  3. 因为生成的数字太大,所以采用米勒测试判断素数。

/*************************************************************************
    > File Name: euler041.c
    > Author:    WArobot 
    > Blog:      http://www.cnblogs.com/WArobot/ 
    > Created Time: 2017年07月01日 星期六 14时46分33秒
 ************************************************************************/

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <algorithm>
#include <inttypes.h>

#define MAX_ROUND 30

int32_t quick_pow(int64_t a , int64_t b , int64_t mod) {
    int64_t ret = 1;
    while (b) {
        if (b & 1)  ret = ret * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ret % mod;
}
bool R_M_TEST(int64_t n) {
    int64_t x;
    for (int32_t i = 0 ; i < MAX_ROUND ; i++) {
        x = (rand() % (n - 1)) + 1;
        if (quick_pow(x , n - 1 , n) != 1)  return false;
    }
    return true;
}

int32_t main() {
    int64_t tmp;
    int32_t num[9] = {0} , flag = 0;
    srand(time(NULL));
    for(int32_t i = 7 ; i >= 1 ; i--) {
        for (int32_t j = 0 ; j < i ; j++)
            num[j] = i - j;
        do {
            tmp = 0;
            for (int32_t j = 0 ; j < i ; j++)
                tmp = tmp * 10 + (int64_t)num[j];
            if (R_M_TEST(tmp)) {
                printf("ans = " "%"PRId64"\n",tmp); 
                flag = 1;   break;
            }
        } while(std::prev_permutation(num , num + i));
        if (flag)   break;
    }
    return 0;
}

转载于:https://www.cnblogs.com/WArobot/p/7102621.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值