欧拉计划41题

Pandigital prime
We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once. For example, 2143 is a 4-digit pandigital and is also prime.
What is the largest n-digit pandigital prime that exists?

 题目:
如果一个数字将 1 到 n 的每个数字都使用且只使用了一次,我们将其称其为一个 n 位的 pandigital 数。例如,2143 是一个 4 位的 pandigital 数,并且是一个质数。
最大的 n 位 pandigital 质数是多少?

        通过题目可以获得两个条件:

        1. 这个数值由1-n组成,n为这个数的位数(1 <= n <= 9)

        2. 这个数是质数

        然后题目要求满足这两个条件中n位最大的数值

        来看下面的式子:

        1 + 2 = 3\\ 1 + 2 + 3 = 6\\ 1 + 2 + 3 + 4 = 10\\ 1 + 2 + 3 + 4 + 5 = 15\\ 1 + 2 + 3 + 4 + 5 + 6 = 21\\ 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28\\ 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 = 36\\ 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 = 45\\

`       只有1-4和1-7的和不是3的倍数,通过所学的数学知识,可以直到,一个数的每位和是3的倍数那这个数因子有3,那也说明这个数不是质数,所以只有在1-4和1-7之间去找存在的质因子并且找到最大的数;

        下面是代码实现:

#include 
#include 
#define MAX_N 10000000


int num4[20], num7[50]; //用来查看当前数是否被用过
int num1[30];//存1-4的数有24种
int num2[6000];//存1-7的数有5040种
char buff[100];//用来存当前的数值
int prime[MAX_N + 5];
int is_prime[MAX_N + 5];

int get_int(char *buff) {//将字符串转换为数值
    int num = 0;
    for (int i = 0; buff[i]; i++) {
        num = num * 10 + buff[i] - '0';
    }
    return num;
}

int s = 1;

void init_foru(int n, int k, char *buff) {//获取4位的包含1-4的数
    if (k == 4) {
        buff[k] = '\0';
        num1[++num1[0]] = get_int(buff);
    }
    for (int i = n; i <= 4; i++) {
        while (num4[s]) {
            if (s == 4) s = 1;
            else s++;
        }
        num4[s] = 1;
        buff[k] = s + '0';
        init_foru(n + 1, k + 1, buff);
        num4[buff[k] - '0'] = 0;
    }
    return ;
}
void init_seven(int n, int k, char *buff) {//获取7位包含1-7的数
    if (k == 7) {
        num2[++num2[0]] = get_int(buff);
        return ;
    }
    for (int i = n; i <= 7; i++) {
        while (num7[s]) {//获取最近的一位未被用的数
            if (s == 7) s = 1;
            else s++;
        }
        num7[s] = 1;//标记当前数已经被用
        buff[k] = s + '0';//讲当前位置输入当前获取未被用的数
        init_seven(n + 1, k + 1, buff);//递归对下一位数组的填充
        num7[buff[k] - '0'] = 0;//回溯进行初始化 
    }
    return ;
}

void init() {//线性筛
    for (int i = 2; 2 * i <= MAX_N; i++) { 
        if (!is_prime[i]) prime[++prime[0]] = i;
        for (int j = 1; prime[j] * i <= MAX_N; j++) {
            is_prime[prime[j] * i] = 1;
            if (i % prime[j] == 0) break;
        }
    }
    return ;
}

int main() {
    init_foru(1, 0, buff);
    s = 1;
    memset(buff, 0, sizeof(buff));
    init_seven(1, 0, buff);
    init();
    long long ans = 0;
    for (int i = 1; i <= num1[0]; i++) {
        if (is_prime[num1[i]]) continue;
        ans = ans > num1[i] ? ans : num1[i];
    }
    for (int i = 1; i <= num2[0]; i++) {
        if (is_prime[num2[i]]) continue;
        ans = ans > num2[i] ? ans : num2[i];
    }
    printf("%lld\n", ans);
    return 0;
}

最终答案: 7652413

你可能感兴趣的:(算法)