add new solutions

This commit is contained in:
Yiyang Kang 2026-02-01 14:56:08 +09:00
parent 67cad91898
commit 51975f3386
Signed by: kkyy
SSH key fingerprint: SHA256:lJSbAzC3MvrSORdvIVK6h/3g+rVKJNzM7zq0MgA9WKY
24 changed files with 933 additions and 14 deletions

View file

@ -0,0 +1,51 @@
package q2976
import "math"
const INF int = math.MaxInt
func minimumCost(source string, target string, original []byte, changed []byte, cost []int) int64 {
mat := make([][]int, 26)
for i := range mat {
mat[i] = make([]int, 26)
mat[0][i] = INF
}
for i := 1; i < 26; i++ {
copy(mat[i], mat[0])
}
q := make([][3]int, 0, 2*len(original)) // src, dst, cost
for i := range original {
src, dst, cst := int(original[i]-'a'), int(changed[i]-'a'), cost[i]
q = append(q, [3]int{src, dst, cst})
mat[src][dst] = min(mat[src][dst], cst)
}
for ; len(q) > 0; q = q[1:] {
src, dst, cst := q[0][0], q[0][1], q[0][2]
for next := range mat {
if next == src || mat[dst][next] == INF {
continue
}
nextCost := mat[dst][next] + cst
if nextCost < mat[src][next] {
mat[src][next] = nextCost
q = append(q, [3]int{src, next, nextCost})
}
}
}
minTotalCost := 0
for i := range len(source) {
if source[i] != target[i] {
src, dst := source[i]-'a', target[i]-'a'
if mat[src][dst] == INF {
return -1
}
minTotalCost += mat[src][dst]
}
}
return int64(minTotalCost)
}
var _ = minimumCost

View file

@ -0,0 +1,96 @@
package q2977
import "math"
const INF int = math.MaxInt
func minimumCost(source string, target string, original []string, changed []string, cost []int) int64 {
// Index words
words := make([]string, 0, len(original)+len(changed))
wIdx := make(map[string]int, len(original)+len(changed))
addWords := func(arr []string) {
for _, word := range arr {
if _, ok := wIdx[word]; !ok {
words = append(words, word)
wIdx[word] = len(words) - 1
}
}
}
addWords(original)
addWords(changed)
// Calculate min cost from `original` to `changed`
mat := make([][]int, len(words))
for i := range mat {
mat[i] = make([]int, len(words))
mat[0][i] = INF
}
for i := 1; i < len(words); i++ {
copy(mat[i], mat[0])
}
q := make([][3]int, 0, 2*len(original)) // src, dst, cost
for i := range original {
src, dst, cst := wIdx[original[i]], wIdx[changed[i]], cost[i]
q = append(q, [3]int{src, dst, cst})
mat[src][dst] = min(mat[src][dst], cst)
}
for ; len(q) > 0; q = q[1:] {
src, dst, cst := q[0][0], q[0][1], q[0][2]
for next := range mat {
if next == src || mat[dst][next] == INF {
continue
}
nextCost := mat[dst][next] + cst
if nextCost < mat[src][next] {
mat[src][next] = nextCost
q = append(q, [3]int{src, next, nextCost})
}
}
}
// Calculate min cost for converting entire string
lengthsT := make(map[int]struct{}, len(original))
for i := range original {
lengthsT[len(original[i])] = struct{}{}
}
lengths := make([]int, 0, len(lengthsT))
for l := range lengthsT {
lengths = append(lengths, l)
}
minCost := make([]int, len(source)+1)
for i := range minCost {
minCost[i] = INF
}
minCost[0] = 0
for i := 1; i < len(minCost); i++ {
if source[i-1] == target[i-1] {
minCost[i] = minCost[i-1]
}
for _, l := range lengths {
if l > i || minCost[i-l] == INF {
continue
}
srcStr, dstStr := source[i-l:i], target[i-l:i]
src, ok1 := wIdx[srcStr]
dst, ok2 := wIdx[dstStr]
if !ok1 || !ok2 || mat[src][dst] == INF {
continue
}
minCost[i] = min(minCost[i], minCost[i-l]+mat[src][dst])
}
}
ret := minCost[len(minCost)-1]
if ret == INF {
return -1
}
return int64(ret)
}
var _ = minimumCost