
2025-06-24:使两个整数相等的数位操作。用go语言,给定两个整数 n 和 m,它们的位数相同。 你可以对 n 执行任意次数的操作,每次操作都是以下两种之一:
在整个操作过程中,数字 n 的值不能是质数。也就是说,初始的 n 以及每次操作完成后的 n 都不能是质数。
操作的总代价定义为 n 变化过程中所有中间值(包括初始和最终值)的和。
请你计算出,将 n 通过上述操作变为 m 所需的最小代价。如果无法完成转换,则返回 -1。
1 <= n, m < 10000。
n 和 m 包含的数位数目相同。
输入:n = 10, m = 12。
输出:85。
解释:
我们执行以下操作:
增加第一个数位,得到 n = 20 。
增加第二个数位,得到 n = 21 。
增加第二个数位,得到 n = 22 。
减少第一个数位,得到 n = 12 。
题目来自力扣3377。
n 到 m 的最小代价路径。n 开始,初始代价为 n。m 时,返回当前的总代价;如果堆为空且未找到 m,则返回 -1。np,大小为 10000,np[i] 为 true 表示 i 是合数或 1。true(非质数)。i 从 2 开始,如果 i 是质数(np[i] 为 false),则标记其所有倍数为合数。n 或 m 是质数,直接返回 -1。dis,大小为 10^len(n)(即所有可能的数字范围),初始值为无穷大。dis[n] 初始化为 n(初始代价)。(n, n) 加入最小堆,表示从 n 出发,当前总代价为 n。x。x == m,返回当前总代价。x 的每一位:d,如果 d > 0,可以减 1 生成新数字 y。d < 9,可以加 1 生成新数字 y。newD = disX + y(disX 是 x 的当前总代价)。y 是合数(或 1)且 newD < dis[y],更新 dis[y] 并将 (newD, y) 加入堆。m,返回 -1。np 数组:O(10000)。dis 数组:O(10000)。.
package main
import (
"container/heap"
"fmt"
"math"
"strconv"
)
const mx = 10000
var np = [mx]bool{1: true}
func init() {
// 埃氏筛,标记每个数是否为合数(或者 1)
for i := 2; i < mx; i++ {
if !np[i] {
for j := i * i; j < mx; j += i {
np[j] = true// 合数
}
}
}
}
func minOperations(n, m int)int {
if !np[n] || !np[m] {
return-1
}
lenN := len(strconv.Itoa(n))
dis := make([]int, int(math.Pow10(lenN)))
for i := range dis {
dis[i] = math.MaxInt
}
dis[n] = n
h := hp{{n, n}}
forlen(h) > 0 {
top := heap.Pop(&h).(pair)
x := top.x
if x == m {
return top.dis
}
disX := top.dis
if disX > dis[x] {
continue
}
pow10 := 1
for v := x; v > 0; v /= 10 {
d := v % 10
if d > 0 { // 减少
y := x - pow10
newD := disX + y
if np[y] && newD < dis[y] {
dis[y] = newD
heap.Push(&h, pair{newD, y})
}
}
if d < 9 { // 增加
y := x + pow10
newD := disX + y
if np[y] && newD < dis[y] {
dis[y] = newD
heap.Push(&h, pair{newD, y})
}
}
pow10 *= 10
}
}
return-1
}
type pair struct{ dis, x int }
type hp []pair
func (h hp) Len() int { returnlen(h) }
func (h hp) Less(i, j int) bool { return h[i].dis < h[j].dis }
func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *hp) Push(v any) { *h = append(*h, v.(pair)) }
func (h *hp) Pop() (v any) { a := *h; *h, v = a[:len(a)-1], a[len(a)-1]; return }
func main() {
n := 10
m := 12
fmt.Println(minOperations(n, m))
}

.
# -*-coding:utf-8-*-
import heapq
import math
MAX = 10000
# np[i] == True 表示 i 是合数或 1,不是质数
np = [False] * MAX
np[1] = True
for i in range(2, int(math.sqrt(MAX)) + 1):
if not np[i]:
for j in range(i * i, MAX, i):
np[j] = True
def min_operations(n: int, m: int) -> int:
if not np[n] or not np[m]:
return-1
len_n = len(str(n))
limit = 10 ** len_n
dis = [math.inf] * limit
dis[n] = n
heap = [(n, n)] # (dist, x)
while heap:
dist_x, x = heapq.heappop(heap)
if x == m:
return dist_x
if dist_x > dis[x]:
continue
pow10 = 1
v = x
digits = []
for _ in range(len_n):
digits.append(v % 10)
v //= 10
for i, d in enumerate(digits):
if d > 0:
y = x - pow10
if y < limit and np[y]:
new_dist = dist_x + y
if new_dist < dis[y]:
dis[y] = new_dist
heapq.heappush(heap, (new_dist, y))
if d < 9:
y = x + pow10
if y < limit and np[y]:
new_dist = dist_x + y
if new_dist < dis[y]:
dis[y] = new_dist
heapq.heappush(heap, (new_dist, y))
pow10 *= 10
return-1
if __name__ == "__main__":
n = 10
m = 12
print(min_operations(n, m))