こんにちは、ナナオです。
前回に引き続き競プロを実施していきたいと思います。
今回の問題は以下です。
【マップの扱い 3】マップの判定・縦横斜め | レベルアップ問題集 | プログラミング学習サイト【paizaラーニング】
実装
最初は以下のように実装しましたが、この実装だとダメでした。
縦横斜めのカラムを反対にするのではなく、すべてのカラムを反対にしているからです。
package main
import "fmt"
func main(){
var h, w, sy, sx int
fmt.Scan(&h, &w)
g := make([]string, h)
for i := 0; i < h; i++ {
fmt.Scan(&g[i])
}
repl := func(sy, sx int, r rune) {
runes := []rune(g[sy])
runes[sx] = r
g[sy] = string(runes)
}
fmt.Scan(&sy, &sx)
for dy := -20; dy <= 20; dy++ {
for dx := -20; dx <= 20; dx++ {
ty, tx := sy + dy, sx + dx
if ty >= 0 && tx >= 0 && ty < h && tx < w {
if g[ty][tx] == '.' {
repl(ty, tx, '#')
} else {
repl(ty, tx, '.')
}
}
}
}
for i := 0; i < h; i++ {
fmt.Println(g[i])
}
}
ということで解答例を見つつ修正します。
package main
import "fmt"
func main(){
var h, w, sy, sx int
fmt.Scan(&h, &w)
g := make([]string, h)
for i := 0; i < h; i++ {
fmt.Scan(&g[i])
}
repl := func(sy, sx int) {
if sy < 0 || sx < 0 || sy >= h || sx >= w {
return
}
runes := []rune(g[sy])
if runes[sx] == '#' {
runes[sx] = '.'
} else {
runes[sx] = '#'
}
g[sy] = string(runes)
}
fmt.Scan(&sy, &sx)
// 縦の処理
for i := 0; i < h; i++ {
if i == sy {
continue
}
repl(i, sx)
}
// 横の処理
for i := 0; i < w; i++ {
if i == sx{
continue
}
repl(sy, i)
}
// 斜めの処理
min := 0
if h > w {
min = w
} else {
min = h
}
for i := 1; i < min; i++ {
repl(sy + i, sx + i)
repl(sy + i, sx - i)
repl(sy - i, sx + i)
repl(sy - i, sx - i)
}
// 原点の処理
repl(sy, sx)
for i := 0; i < h; i++ {
fmt.Println(g[i])
}
}
これで実装できました。
repl関数で判定を寄せましたが、このおかげで割とすっきりかけましたね。
ということで今回はこれで👍