Prime Path,POJ,3126

题目描述(Prime Path, POJ 3126)

给定两个四位数质数A和B,要求找到从A到B的最短转换路径,每次转换只能改变一个数字,并且转换后的数也必须是一个质数。

解题思路

  1. 质数筛选
    • 使用埃拉托斯特尼筛法(Sieve of Eratosthenes)生成所有四位数质数的列表。
  2. 图的构建
    • 将每个四位数质数看作图中的一个节点。
    • 如果两个质数之间只有一个数字不同,则在这两个节点之间建立一条边。
  3. 广度优先搜索(BFS)
    • 从起始质数A开始,使用BFS搜索到目标质数B的最短路径。

详细步骤

  1. 生成四位数质数列表
    • 初始化一个布尔数组isPrime,标记1000到9999之间的每个数是否为质数。
    • 使用筛法标记非质数。
    • 收集所有标记为质数的四位数。
  2. 构建邻接表
    • 对于每个四位数质数,尝试改变每一位(0-9),检查新数是否为质数且与原数不同。
    • 如果是,则在邻接表中添加一条边。
  3. BFS搜索最短路径
    • 使用队列进行BFS,记录每个节点的层次(即转换次数)。
    • 从A开始,逐层扩展,直到找到B,记录转换次数。

代码实现(Python示例)

def sieve_of_eratosthenes(max_num): is_prime = [True] (max_num + 1) p = 2 while (p p <= max_num): if (is_prime[p] == True): for i in range(p * p, max_num + 1, p): is_prime[i] = False p += 1 is_prime[0], is_prime[1] = False, False return [p for p in range(1000, 10000) if is_prime[p]]

def build_adjacency_list(primes): adj_list = {prime: [] for prime in primes} for prime in primes: prime_str = str(prime) for i in range(4): for digit in '0123456789': if digit != prime_str[i]: new_num = int(prime_str[:i] + digit + prime_str[i+1:]) if new_num >= 1000 and new_num in primes: adj_list[prime].append(new_num) return adj_list

def bfs_shortest_path(adj_list, start, end): from collections import deque queue = deque([(start, 0)]) visited = set([start]) while queue: current, steps = queue.popleft() if current == end: return steps for neighbor in adj_list[current]: if neighbor not in visited: visited.add(neighbor) queue.append((neighbor, steps + 1)) return -1

def main(): import sys input = sys.stdin.read data = input().split() A = int(data[0]) B = int(data[1])

primes = sieve_of_eratosthenes(9999)
adj_list = build_adjacency_list(primes)
result = bfs_shortest_path(adj_list, A, B)
print(result)

if name == "main": main()

解释

  1. sieve_of_eratosthenes:生成1000到9999之间的所有质数。
  2. build_adjacency_list:构建质数之间的邻接表。
  3. bfs_shortest_path:使用BFS找到从A到B的最短路径。
  4. main:读取输入,调用函数,输出结果。

注意事项

  • 确保输入的A和B都是四位数质数。
  • 处理边界情况,如A和B相同的情况。

通过上述步骤和代码,可以有效地解决Prime Path问题。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注