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

📅  最后修改于: 2021-10-26 05:40:17             🧑  作者: Mango

给定一个数 N,任务是找到小于或等于给定数 N 的最大数,这样在重新排列它的数字时它可以成为质数。

例子:

Input : N = 99 
Output : 98
Explanation : We can rearrange the digits of 
98 to 89 and 89 is a prime number. 

Input : N = 84896
Output : 84896
Explanation : We can rearrange the digits of 
84896 to 46889 which is a prime number.

下面是找到这样一个最大数num <= N的算法,这样 num 的数字可以重新排列以获得质数:

预处理步骤:生成所有小于或等于给定数 N 的素数的列表。这可以使用 Eratosthenes 筛有效地完成。

主要步骤: 主要思想是检查从 N 到 1 的所有数字,如果其中任何一个数字可以重新排列形成素数。找到的第一个这样的数字就是答案。

为此,请为每个数字运行从 N 到 1 的循环:

  1. 提取给定数字的数字并将其存储在向量中。
  2. 对该向量进行排序以获得可以使用这些数字形成的最小数字。
  3. 对于这个向量的每个排列,我们会形成一个数字并检查所形成的数字是否是素数。这里我们使用预处理步骤。
  4. 如果它是质数,那么我们停止循环,这就是我们的答案。

下面是上述方法的实现:

C++
// C++ Program to find a number less than
// or equal to N such that rearranging
// the digits gets a prime number
  
#include 
using namespace std;
  
// Preprocessed vector to store primes
vector prime(1000001, true);
  
// Function to generate primes using
// sieve of eratosthenese
void sieve()
{
    // Applying sieve of Eratosthenes
    prime[0] = prime[1] = false;
  
    for (long long i = 2; i * i <= 1000000; i++) {
  
        if (prime[i]) {
            for (long long j = i * i; j <= 1000000; j += i)
                prime[j] = false;
        }
    }
}
  
// Function to find a number less than
// or equal to N such that rearranging
// the digits gets a prime number
int findNumber(int n)
{
    vector v;
    bool flag = false;
  
    int num;
  
    // Run loop from n to 1
    for (num = n; num >= 1; num--) {
  
        int x = num;
  
        // Clearing the vector
        v.clear();
  
        // Extracting the digits
        while (x != 0) {
            v.push_back(x % 10);
  
            x /= 10;
        }
  
        // Sorting the vector to make smallest
        // number using digits
        sort(v.begin(), v.end());
  
        // Check all permutation of current number
        // for primality
        while (1) {
            long long w = 0;
  
            // Traverse vector to for number
            for (auto u : v)
                w = w * 10 + u;
  
            // If prime exists
            if (prime[w]) {
  
                flag = true;
                break;
            }
  
            if (flag)
                break;
  
            // generating next permutation of vector
            if (!next_permutation(v.begin(), v.end()))
                break;
        }
  
        if (flag)
            break;
    }
  
    // Required number
    return num;
}
  
// Driver Code
int main()
{
    sieve();
  
    int n = 99;
    cout << findNumber(n) << endl;
  
    n = 84896;
    cout << findNumber(n) << endl;
  
    return 0;
}


Python3
# Python 3 Program to find a number less than
# or equal to N such that rearranging
# the digits gets a prime number
from math import sqrt
  
def next_permutation(a):
      
    # Generate the lexicographically 
    # next permutation inplace.
  
    # https://en.wikipedia.org/wiki/Permutation
    # Generation_in_lexicographic_order
    # Return false if there is no next permutation.
  
    # Find the largest index i such that 
    # a[i] < a[i + 1]. If no such index exists, 
    # the permutation is the last permutation
    for i in reversed(range(len(a) - 1)):
        if a[i] < a[i + 1]:
            break # found
    else: # no break: not found
        return False # no next permutation
  
    # Find the largest index j greater than i
    # such that a[i] < a[j]
    j = next(j for j in reversed(range(i + 1, len(a))) 
                                      if a[i] < a[j])
  
    # Swap the value of a[i] with that of a[j]
    a[i], a[j] = a[j], a[i]
  
    # Reverse sequence from a[i + 1] up to and
    # including the final element a[n]
    a[i + 1:] = reversed(a[i + 1:])
    return True
  
# Preprocessed vector to store primes
prime = [True for i in range(1000001)]
  
# Function to generate primes using
# sieve of eratosthenese
def sieve():
      
    # Applying sieve of Eratosthenes
    prime[0] = False
    prime[1] = False
  
    for i in range(2,int(sqrt(1000000)) + 1, 1):
        if (prime[i]):
            for j in range(i * i, 1000001, i):
                prime[j] = False
  
# Function to find a number less than
# or equal to N such that rearranging
# the digits gets a prime number
def findNumber(n):
    v = []
    flag = False
      
    # Run loop from n to 1
    num = n
    while(num >= 1):
        x = num
          
        v.clear()
  
        # Extracting the digits
        while (x != 0):
            v.append(x % 10)
  
            x = int(x / 10)
  
        # Sorting the vector to make smallest
        # number using digits
        v.sort(reverse = False)
  
        # Check all permutation of current number
        # for primality
        while (1):
            w = 0
  
            # Traverse vector to for number
            for u in v:
                w = w * 10 + u
  
            # If prime exists
            if (prime[w]):
                flag = True
                break
  
            if (flag):
                break
  
            # generating next permutation of vector
            if (next_permutation(v) == False):
                break
  
        if (flag):
            break
          
        num -= 1
  
    # Required number
    return num
  
# Driver Code
if __name__ == '__main__':
    sieve()
  
    n = 99
    print(findNumber(n))
  
    n = 84896
    print(findNumber(n))
  
# This code is contributed by
# Surendra_Gangwar


输出:
98
84896

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。