📜  重排后可以成为质数的不大于N的最大数(1)

📅  最后修改于: 2023-12-03 15:12:29.801000             🧑  作者: Mango

重排后可以成为质数的不大于N的最大数

在数学中,质数指的是只能被1和本身整除的正整数。对于一个数,如果它的数字排列可以重新排列成另一个质数,那么就称这个数为可重排质数。

本文将介绍如何找到重排后可以成为质数的不大于N的最大数。

解法

首先,我们可以使用一个布尔型数组来表示质数,数组下标代表数值,数组元素为true表示是质数,为false则不是。对于每个数,我们可以通过试除法来判断它是否为质数。如果它是质数,我们就可以将其所有排列方式中的质数都标记出来,然后选择最大的可重排质数即可。

具体实现过程如下:

  1. 定义一个布尔型数组isPrime,大小为N+1,初始值都为true。

    boolean[] isPrime = new boolean[N+1];
    Arrays.fill(isPrime, true);
    
  2. 使用试除法来更新isPrime数组。对于每个数i,从2到i-1的每个数j都尝试去整除i,如果有整除结果为0的j,则i不是质数,将isPrime[i]设为false。

    for (int i = 2; i <= N; i++) {
        for (int j = 2; j < i; j++) {
            if (i % j == 0) {
                isPrime[i] = false;
                break;
            }
        }
    }
    
  3. 对于每个质数i,生成它的所有排列方式;然后针对每种排列方式,检查该排列是否为质数,如果是,则将该排列映射到原始数值,并记录该数值是否被使用过。选择找到的最大值即可。

    int max = -1;
    boolean[] used = new boolean[N+1];
    for (int i = 2; i <= N; i++) {
        if (!isPrime[i]) continue;
        char[] chars = String.valueOf(i).toCharArray();
        int[] count = new int[10];
        for (char c : chars) {
            count[c-'0']++;
        }
        List<Integer> permutations = new ArrayList<>();
        permute(count, 0, 0, permutations);
        for (int j : permutations) {
            int num = convert(j, chars.length);
            if (num > N || !isPrime[num] || used[num]) continue;
            used[num] = true;
            max = Math.max(max, num);
        }
    }
    
  4. 最终返回找到的最大值。

    return max;
    
完整代码
public int maxPrime(int N) {
    boolean[] isPrime = new boolean[N+1];
    Arrays.fill(isPrime, true);
    for (int i = 2; i <= N; i++) {
        for (int j = 2; j < i; j++) {
            if (i % j == 0) {
                isPrime[i] = false;
                break;
            }
        }
    }
    int max = -1;
    boolean[] used = new boolean[N+1];
    for (int i = 2; i <= N; i++) {
        if (!isPrime[i]) continue;
        char[] chars = String.valueOf(i).toCharArray();
        int[] count = new int[10];
        for (char c : chars) {
            count[c-'0']++;
        }
        List<Integer> permutations = new ArrayList<>();
        permute(count, 0, 0, permutations);
        for (int j : permutations) {
            int num = convert(j, chars.length);
            if (num > N || !isPrime[num] || used[num]) continue;
            used[num] = true;
            max = Math.max(max, num);
        }
    }
    return max;
}

private void permute(int[] count, int num, int depth, List<Integer> res) {
    if (depth == count.length) {
        res.add(num);
        return;
    }
    for (int i = 0; i < count.length; i++) {
        if (count[i] == 0) continue;
        count[i]--;
        permute(count, num*10+i, depth+1, res);
        count[i]++;
    }
}

private int convert(int num, int length) {
    int res = 0;
    while (num > 0) {
        res = res*10 + num%10;
        num /= 10;
    }
    while (length-- > 0) {
        res *= 10;
    }
    return res;
}
总结

本文介绍了如何找到重排后可以成为质数的不大于N的最大数。我们可以使用一个布尔型数组来表示质数,使用试除法来更新数组,然后针对每个质数,生成它的所有排列方式,检查是否为质数,并记录被使用过的数值。最后选择找到的最大值即可。