题意:如果一个n位数恰好使用了1至n每个数字各一次,我们就称其为全数字的。例如,2143就是一个4位全数字数,同时它恰好也是一个素数。
最大的全数字的素数是多少?
思路:
- 最大全排列素数可以从 n = 9 使用 perv_permutation 倒序生成。
- 当 n = 9 或者 n = 8 时生成的全排列构成的数一定不是素数,因为它一定能被 3 整除,所以从 7 开始枚举。
- 因为生成的数字太大,所以采用米勒测试判断素数。
/*************************************************************************
> 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"
",tmp);
flag = 1; break;
}
} while(std::prev_permutation(num , num + i));
if (flag) break;
}
return 0;
}