こんにちは、ナナオです。
前回に引き続き競プロを実施していきたいと思います。
今回の問題は以下です。
幅のある移動 | レベルアップ問題集 | プログラミング学習サイト【paizaラーニング】
実装
ちょっと悩んでAIとも壁打ちした結果、queueという仕組みを使うのが一番効率的なんだと分かりました。
package main
import (
"fmt"
"strconv"
)
func main(){
var h, w int
fmt.Scan(&h, &w)
s := make([]string, h)
replace := func(sy, sx, r int) {
runes := []rune(s[sy])
runes[sx] = rune(48 + r)
s[sy] = string(runes)
}
var queueY, queueX []int
for i := 0; i < h; i++ {
fmt.Scan(&s[i])
for j, v := range s[i] {
if v == '*' {
replace(i, j, 0)
queueY = append(queueY, i)
queueX = append(queueX, j)
}
}
}
// 移動方向(上下左右)
dy := []int{1, -1, 0, 0}
dx := []int{0, 0, 1, -1}
for len(queueY) > 0 {
sy, sx := queueY[0], queueX[0]
queueY, queueX = queueY[1:], queueX[1:]
r, _ := strconv.Atoi(string(s[sy][sx]))
var ly, lx int
for i := 0; i < 4; i++ {
ly, lx = sy + dy[i], sx + dx[i]
if ly >= 0 && lx >= 0 && ly < h && lx < w && s[ly][lx] == '.' {
replace(ly, lx, r + 1)
queueY = append(queueY, ly)
queueX = append(queueX, lx)
}
}
}
for i := 0; i < h; i++ {
fmt.Println(s[i])
}
}
queue周りの実装はもう少しいい感じにできた気がしなくもないですが、とりあえずまぁこれで…