📌  相关文章
📜  通过一次更改一位数达到一个素数的最短路径

📅  最后修改于: 2022-05-13 01:57:54.168000             🧑  作者: Mango

通过一次更改一位数达到一个素数的最短路径

给定两个四位素数,假设 1033 和 8179,我们需要通过一次仅更改一位数来找到从 1033 到 8179 的最短路径,使得我们在更改一位后得到的每个数字都是素数。例如,解决方案是 1033、1733、3733、3739、3779、8779、8179

例子:

Input : 1033 8179
Output :6

Input : 1373 8017
Output : 7

Input  :  1033 1033
Output : 0

这个问题可以通过BFS解决,作为初学者的起始问题来解决是一个非常有趣的问题。我们首先使用 Eratosthenes 筛法找出 9999 之前的所有 4 位素数。然后使用这些数字使用邻接表形成图形。形成邻接表后,我们使用简单的 BFS 来解决问题。

C++
// CPP program to reach a prime number from 
// another by changing single digits and 
// using only prime numbers.
#include 
  
using namespace std;
  
class graph {
    int V; 
    list* l; 
public:
    graph(int V)
    {
        this->V = V;
        l = new list[V];
    }
    void addedge(int V1, int V2) 
    {
        l[V1].push_back(V2);
        l[V2].push_back(V1);
    }
    int bfs(int in1, int in2);
};
  
// Finding all 4 digit prime numbers
void SieveOfEratosthenes(vector& v) 
{
    // Create a boolean array "prime[0..n]" and initialize
    // all entries it as true. A value in prime[i] will
    // finally be false if i is Not a prime, else true.
    int n = 9999;
    bool prime[n + 1];
    memset(prime, true, sizeof(prime));
  
    for (int p = 2; p * p <= n; p++) {
  
        // If prime[p] is not changed, then it is a prime
        if (prime[p] == true) {
  
            // Update all multiples of p
            for (int i = p * p; i <= n; i += p)
                prime[i] = false;
        }
    }
  
    // Forming a vector of prime numbers
    for (int p = 1000; p <= n; p++)
        if (prime[p])
            v.push_back(p); 
}
  
// in1 and in2 are two vertices of graph which are 
// actually indexes in pset[]
int graph::bfs(int in1, int in2) 
{
    int visited[V];
    memset(visited, 0, sizeof(visited));
    queue que;
    visited[in1] = 1;
    que.push(in1);
    list::iterator i;
    while (!que.empty()) {
        int p = que.front();
        que.pop();
        for (i = l[p].begin(); i != l[p].end(); i++) {
            if (!visited[*i]) {
                visited[*i] = visited[p] + 1;
                que.push(*i);
            }
            if (*i == in2) {
                return visited[*i] - 1;
            }
        }
    }
}
  
// Returns true if num1 and num2 differ 
// by single digit.
bool compare(int num1, int num2)
{
    // To compare the digits
    string s1 = to_string(num1);
    string s2 = to_string(num2);
    int c = 0;
    if (s1[0] != s2[0])
        c++;
    if (s1[1] != s2[1])
        c++;
    if (s1[2] != s2[2])
        c++;
    if (s1[3] != s2[3])
        c++;
  
    // If the numbers differ only by a single
    // digit return true else false
    return (c == 1);
}
  
int shortestPath(int num1, int num2)
{
    // Generate all 4 digit
    vector pset; 
    SieveOfEratosthenes(pset);
  
  
    // Create a graph where node numbers are indexes
    // in pset[] and there is an edge between two 
    // nodes only if they differ by single digit.
    graph g(pset.size()); 
    for (int i = 0; i < pset.size(); i++) 
        for (int j = i + 1; j < pset.size(); j++) 
            if (compare(pset[i], pset[j]))
                g.addedge(i, j);     
      
  
    // Since graph nodes represent indexes of numbers
    // in pset[], we find indexes of num1 and num2.
    int in1, in2;
    for (int j = 0; j < pset.size(); j++) 
        if (pset[j] == num1)
            in1 = j; 
    for (int j = 0; j < pset.size(); j++) 
        if (pset[j] == num2)
            in2 = j; 
  
    return g.bfs(in1, in2);
}
  
// Driver code
int main()
{
    int num1 = 1033, num2 = 8179;
    cout << shortestPath(num1, num2);
    return 0;
}


Python3
# Python3 program to reach a prime number 
# from another by changing single digits  
# and using only prime numbers.
import queue 
  
class Graph: 
      
    def __init__(self, V):
        self.V = V; 
        self.l = [[] for i in range(V)]
          
    def addedge(self, V1, V2):
        self.l[V1].append(V2); 
        self.l[V2].append(V1);
  
    # in1 and in2 are two vertices of graph  
    # which are actually indexes in pset[] 
    def bfs(self, in1, in2):
        visited = [0] * self.V
        que = queue.Queue()
        visited[in1] = 1
        que.put(in1)
        while (not que.empty()): 
            p = que.queue[0] 
            que.get()
            i = 0
            while i < len(self.l[p]):
                if (not visited[self.l[p][i]]):
                    visited[self.l[p][i]] = visited[p] + 1
                    que.put(self.l[p][i])
                if (self.l[p][i] == in2):
                    return visited[self.l[p][i]] - 1
                i += 1
      
    # Returns true if num1 and num2 
    # differ by single digit.
      
# Finding all 4 digit prime numbers 
def SieveOfEratosthenes(v):
      
    # Create a boolean array "prime[0..n]" and  
    # initialize all entries it as true. A value 
    # in prime[i] will finally be false if i is 
    # Not a prime, else true. 
    n = 9999
    prime = [True] * (n + 1)
  
    p = 2
    while p * p <= n:
  
        # If prime[p] is not changed, 
        # then it is a prime 
        if (prime[p] == True):
  
            # Update all multiples of p
            for i in range(p * p, n + 1, p):
                prime[i] = False
        p += 1
  
    # Forming a vector of prime numbers
    for p in range(1000, n + 1):
        if (prime[p]): 
            v.append(p)
      
def compare(num1, num2):
      
    # To compare the digits 
    s1 = str(num1) 
    s2 = str(num2)
    c = 0
    if (s1[0] != s2[0]):
        c += 1
    if (s1[1] != s2[1]):
        c += 1
    if (s1[2] != s2[2]):
        c += 1
    if (s1[3] != s2[3]): 
        c += 1
  
    # If the numbers differ only by a single 
    # digit return true else false 
    return (c == 1)
      
def shortestPath(num1, num2):
      
    # Generate all 4 digit 
    pset = [] 
    SieveOfEratosthenes(pset) 
  
    # Create a graph where node numbers 
    # are indexes in pset[] and there is 
    # an edge between two nodes only if 
    # they differ by single digit. 
    g = Graph(len(pset))
    for i in range(len(pset)):
        for j in range(i + 1, len(pset)):
            if (compare(pset[i], pset[j])): 
                g.addedge(i, j)     
  
    # Since graph nodes represent indexes 
    # of numbers in pset[], we find indexes
    # of num1 and num2. 
    in1, in2 = None, None
    for j in range(len(pset)):
        if (pset[j] == num1):
            in1 = j
    for j in range(len(pset)):
        if (pset[j] == num2): 
            in2 = j
  
    return g.bfs(in1, in2)
  
# Driver code 
if __name__ == '__main__':
  
    num1 = 1033
    num2 = 8179
    print(shortestPath(num1, num2))
  
# This code is contributed by PranchalK



输出 :
6