📌  相关文章
📜  通过在每一步中替换一个数字,将 N 位素数转换为另一个素数的最小步骤

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

给定两个N位数素数AB ,任务是找到将 A 转换为 B 所采取的最少步骤数。转换的条件是当前素数中只有 1 位可以修改,使得新数形成也是一个质数。如果没有这样的转换是可能的,打印 -1。

注: N 的取值范围为 [1, 5]。

例子:

方法:使用广度优先搜索算法

  1. 找出所有 N 位素数,并用这些数作图。
  2. 将每个素数视为图的一个节点,如果它们相差一位数,则创建从一个节点到另一个节点的边。
  3. 应用 BFS 遍历并找出 A 和 B 之间的边数。
  4. 如果不存在路径,则打印 -1。
  5. 否则打印编号。的边缘,这是所需的解决方案。

下面是上述方法的实现。

C++
// C++ program for the above problem
 
#include 
using namespace std;
 
#define ll long long
#define mod 1000000007
#define pb push_back
#define mod 1000000007
#define vi vector
 
// adjacency list for numbers
// till 100001
vi lis[100001];
vi primes;
 
// visited array
int vis[100001];
 
// to store distance of every
// vertex from A
int dis[100001];
 
// function to check if number
// is a prime
bool isPrime(int n)
{
    for (int i = 2;
         i * i <= n; i++) {
        if (n % i == 0)
            return false;
    }
    return true;
}
 
// function to check if numbers
// differ by only a single-digit
bool valid(int a, int b)
{
    int c = 0;
    while (a) {
 
        // check the last digit of
        // both numbers and increase
        // count if different
        if ((a % 10) != (b % 10)) {
            c++;
        }
        a = a / 10;
        b = b / 10;
    }
    if (c == 1) {
        return true;
    }
    else {
        return false;
    }
}
 
void makePrimes(int N)
{
    int i, j;
    int L = pow(10, N - 1);
    int R = pow(10, N) - 1;
    // generate all N digit primes
    for (int i = L; i <= R; i++) {
        if (isPrime(i)) {
            primes.pb(i);
        }
    }
    for (i = 0;
         i < primes.size(); i++) {
 
        // for every prime number i
        // check if an edge
        // can be made.
        for (j = i + 1;
             j < primes.size(); j++) {
            int a = primes[i];
            int b = primes[j];
 
            // for every prime number
            // i check if an edge can
            // be made from i to j.
            if (valid(a, b)) {
 
                // if edge is possible then
                // insert in the adjacency
                // list
                lis[a].pb(b);
                lis[b].pb(a);
            }
        }
    }
}
 
// function to count distance
void bfs(int src)
{
    queue q;
    q.push(src);
    vis[src] = 1;
    dis[src] = 0;
    while (!q.empty()) {
        int curr = q.front();
        q.pop();
        for (int x : lis[curr]) {
 
            // if unvisited push onto queue
            // and mark visited as 1 and
            // add the distance of curr+1.
            if (vis[x] == 0) {
                vis[x] = 1;
                q.push(x);
                dis[x] = dis[curr] + 1;
            }
        }
    }
}
 
// Driver code
int main()
{
    int N = 4;
    makePrimes(N);
    int A = 1033, B = 8179;
 
    // Call bfs traversal
    // with root as node A
    bfs(A);
 
    if (dis[B] == -1)
       
        // Indicates not possible
        cout << "-1" << endl;
    else
        cout << dis[B] << endl;
 
    return 0;
}


Java
// Java program for the above problem
import java.util.*;
public class GFG
{
 
  // Adjacency list for numbers
  // till 100001
  static Vector> lis = new Vector>();    
  static Vector primes = new Vector();
 
  // Visited array
  static int[] vis = new int[100001];
 
  // To store distance of every
  // vertex from A
  static int[] dis = new int[100001];
 
  // Function to check if number
  // is a prime
  static boolean isPrime(int n)
  {
    int i = 2;
    while (i * i <= n)
    {
      if (n % i == 0)
        return false;
      i += 1;
    }
    return true;
  }
 
  // Function to check if numbers
  // differ by only a single-digit
  static boolean valid(int a, int b)
  {
    int c = 0;       
    while(a > 0)
    {
 
      // Check the last digit of
      // both numbers and increase
      // count if different
      if ((a % 10) != (b % 10))
        c += 1;            
      a = a / 10;
      b = b / 10;
    }    
    if (c == 1)
      return true;
    else
      return false;
  }
 
  static void makePrimes(int N)
  {
 
    // Generate all N digit primes
    int L = (int)Math.pow(10, N - 1);
    int R = (int)Math.pow(10, N) - 1;
 
    for(int i = L; i < R + 1; i++)
    {
      if (isPrime(i))
        primes.add(i);
    }
 
    for(int i = 0; i < primes.size(); i++)
    {
 
      // For every prime number i
      // check if an edge
      // can be made.
      for(int j = i + 1; j < primes.size(); j++)
      {
        int a = primes.get(i);
        int b = primes.get(j);
 
        // For every prime number
        // i check if an edge can
        // be made from i to j.
        if (valid(a, b))
        {
 
          // If edge is possible then
          // insert in the adjacency
          // list
          lis.get(a).add(b);
          lis.get(b).add(a);
        }
      }
    }
  }
 
  // Function to count distance
  static void bfs(int src)
  {
    Vector q = new Vector();
    q.add(src);
    vis[src] = 1;
    dis[src] = 0;
    while (q.size() != 0)
    {
      int curr = q.get(0);
      q.remove(0);
      for(int x : lis.get(curr))
      {
        // If unvisited push onto queue
        // and mark visited as 1 and
        // add the distance of curr+1.
        if (vis[x] == 0)
        {
          vis[x] = 1;
          q.add(x);
          dis[x] = dis[curr] + 1;
        }
      }
    }
  }
 
  // Driver code
  public static void main(String[] args)
  {
    for(int i = 0; i < 100001; i++)
    {
      lis.add(new Vector());
    }
    int N = 4;
    makePrimes(N);
    int A = 1033;
    int B = 8179;
 
    // Call bfs traversal
    // with root as node A
    bfs(A);
 
    if (dis[B] == -1)
    {
      // Indicates not possible
      System.out.print(-1);
    }
    else
    {
      System.out.print(dis[B]);
    }
  }
}
 
// This code is contributed by divyesh072019


Python3
# Python3 program for the above problem
mod = 1000000007
 
# Adjacency list for numbers
# till 100001
lis = [[] for i in range(100001)]
primes = []
 
# Visited array
vis = [0 for i in range(100001)]
 
# To store distance of every
# vertex from A
dis = [0 for i in range(100001)]
 
# Function to check if number
# is a prime
def isPrime(n):
     
    i = 2
    while (i * i <= n):
        if (n % i == 0):
            return False
             
        i += 1
         
    return True
 
# Function to check if numbers
# differ by only a single-digit
def valid(a, b):
     
    c = 0
     
    while(a):
         
        # Check the last digit of
        # both numbers and increase
        # count if different
        if ((a % 10) != (b % 10)):
            c += 1
             
        a = int(a / 10)
        b = int(b / 10)
 
    if (c == 1):
        return True
    else:
        return False
 
def makePrimes(N):
     
    global primes
    global lis
    i = 0
    j = 0
     
    # Generate all N digit primes
    L = pow(10, N - 1)
    R = pow(10, N) - 1
 
    for i in range(L, R + 1):
        if (isPrime(i)):
            primes.append(i)
             
    for i in range(len(primes)):
         
        # For every prime number i
        # check if an edge
        # can be made.
        for j in range(i + 1, len(primes)):
            a = primes[i]
            b = primes[j]
 
            # For every prime number
            # i check if an edge can
            # be made from i to j.
            if (valid(a, b)):
                 
                # If edge is possible then
                # insert in the adjacency
                # list
                lis[a].append(b)
                lis[b].append(a)
 
# Function to count distance
def bfs(src):
     
    global vis
    global dis
    q = []
    q.append(src)
    vis[src] = 1
    dis[src] = 0
 
    while (len(q) != 0):
        curr = q[0]
        q.pop(0)
         
        for x in lis[curr]:
             
            # If unvisited push onto queue
            # and mark visited as 1 and
            # add the distance of curr+1.
            if (vis[x] == 0):
                vis[x] = 1
                q.append(x)
                dis[x] = dis[curr] + 1
 
# Driver code
N = 4
makePrimes(N)
A = 1033
B = 8179
 
# Call bfs traversal
# with root as node A
bfs(A)
 
if (dis[B] == -1):
     
    # Indicates not possible
    print(-1)
else:
    print(dis[B])
 
# This code is contributed by avanitrachhadiya2155


C#
// C# program for the above problem
using System;
using System.Collections.Generic;
class GFG {
  
    // Adjacency list for numbers
    // till 100001
    static List> lis = new List>();
     
    static List primes = new List();
      
    // Visited array
    static int[] vis = new int[100001];
      
    // To store distance of every
    // vertex from A
    static int[] dis = new int[100001];
     
    // Function to check if number
    // is a prime
    static bool isPrime(int n)
    {
        int i = 2;
        while (i * i <= n)
        {
            if (n % i == 0)
                return false;
            i += 1;
        }
        return true;
    }
     
    // Function to check if numbers
    // differ by only a single-digit
    static bool valid(int a, int b)
    {
        int c = 0;
          
        while(a > 0)
        {
            // Check the last digit of
            // both numbers and increase
            // count if different
            if ((a % 10) != (b % 10))
                c += 1;
                  
            a = a / 10;
            b = b / 10;
        }
      
        if (c == 1)
            return true;
        else
            return false;
    }
     
    static void makePrimes(int N)
    {
       
        // Generate all N digit primes
        int L = (int)Math.Pow(10, N - 1);
        int R = (int)Math.Pow(10, N) - 1;
      
        for(int i = L; i < R + 1; i++)
        {
            if (isPrime(i))
                primes.Add(i);
        }
                  
        for(int i = 0; i < primes.Count; i++)
        {
           
            // For every prime number i
            // check if an edge
            // can be made.
            for(int j = i + 1; j < primes.Count; j++)
            {
                int a = primes[i];
                int b = primes[j];
      
                // For every prime number
                // i check if an edge can
                // be made from i to j.
                if (valid(a, b))
                {
                    // If edge is possible then
                    // insert in the adjacency
                    // list
                    lis[a].Add(b);
                    lis[b].Add(a);
                }
            }
        }
    }
     
    // Function to count distance
    static void bfs(int src)
    {
        List q = new List();
        q.Add(src);
        vis[src] = 1;
        dis[src] = 0;
      
        while (q.Count != 0)
        {
            int curr = q[0];
            q.RemoveAt(0);
              
            foreach(int x in lis[curr])
            {
                // If unvisited push onto queue
                // and mark visited as 1 and
                // add the distance of curr+1.
                if (vis[x] == 0)
                {
                    vis[x] = 1;
                    q.Add(x);
                    dis[x] = dis[curr] + 1;
                }
            }
        }
    }
 
  // Driver code
  static void Main()
  {
    for(int i = 0; i < 100001; i++)
    {
        lis.Add(new List());
    }
    int N = 4;
    makePrimes(N);
    int A = 1033;
    int B = 8179;
      
    // Call bfs traversal
    // with root as node A
    bfs(A);
      
    if (dis[B] == -1)
    {
        // Indicates not possible
        Console.Write(-1);
    }
    else
    {
        Console.Write(dis[B]);
    }
  }
}


输出:
6

时间复杂度: O(10 2N )
辅助空间复杂度: O(10 5 )