技巧
df***r />
思路
抽象成二维数组。按照从上到下 从右往左的顺序去尝试每一个字母
注意剪枝和basecase的进位处理
实现
package main
import (
"bufio"
. "fmt"
"io"
"os"
)
func init() {
for i := 0; i < 30; i++ {
vis[i] = -1
}
}
var (
vis = [30]int{} // 字母对应用到的数字
numused = [30]bool{} // 每个数字是否已经使用过了
)
func dfs(expressions []string, row, col, n, step int) {
if col < 0 {
if step != 0 {
return
}
for i := 0; i < n-1; i++ {
Printf("%d ", vis[i])
}
Printf("%d\n", vis[n-1])
return
}
// 剪枝
for i := 0; i < col; i++ {
x := vis[expressions[0][i]-'A']
y := vis[expressions[1][i]-'A']
z := vis[expressions[2][i]-'A']
if x == -1 || y == -1 || z == -1 {
continue
}
if (x+y)%n == z || (x+y+1)%n == z {
continue
} else {
return
}
}
if vis[expressions[row][col]-'A'] != -1 { // 该字母已经被赋值了
if row == 2 { // 最后一行
subtotal := vis[expressions[0][col]-'A'] + vis[expressions[1][col]-'A'] + step
if subtotal%n != vis[expressions[2][col]-'A'] {
return
}
dfs(expressions, 0, col-1, n, subtotal/n)
} else { // 不是最后一行
dfs(expressions, row+1, col, n, step)
}
} else { // 该字母未被赋值
for i := n - 1; i >= 0; i-- {
if numused[i] {
continue
}
if row == 2 { // 最后一行
subtotal := vis[expressions[0][col]-'A'] + vis[expressions[1][col]-'A'] + step
if i != subtotal%n {
continue
}
numused[i] = true
vis[expressions[row][col]-'A'] = i
dfs(expressions, 0, col-1, n, subtotal/n)
vis[expressions[row][col]-'A'] = -1
numused[i] = false
} else { // 不是最后一行
numused[i] = true
vis[expressions[row][col]-'A'] = i
dfs(expressions, row+1, col, n, step)
vis[expressions[row][col]-'A'] = -1
numused[i] = false
}
}
}
}
func NC16665(_r io.Reader, _w io.Writer) {
in, out := bufio.NewReader(_r), bufio.NewWriter(_w)
defer out.Flush()
var N int
Fscan(in, &N)
expressions := make([]string, N)
for i := 0; i < N; i++ {
Fscan(in, &expressions[i])
}
dfs(expressions, 0, N-1, N, 0)
}
func main() {
NC16665(os.Stdin, os.Stdout)
}

京公网安备 11010502036488号