こんにちは、ナナオです。

前回に引き続き競プロを実施していきたいと思います。

今回の問題は以下です。

へび | レベルアップ問題集 | プログラミング学習サイト【paizaラーニング】

ついにボス…!

実装

以下のように実装しました。

package main
import "fmt"
func main(){
    var h, w, sy, sx, n int
    fmt.Scan(&h, &w, &sy, &sx, &n)
    
    s := make([]string, h)
    for i := 0; i < h; i++ {
        fmt.Scan(&s[i])
    }
    
    dir := []string{"N", "E", "S", "W"}
    ct := 0
    cd := 120
    
    // 初期の座標に印をつける
    runes := []rune(s[sy])
    runes[sx] = '*'
    s[sy] = string(runes)
    
    for i := 0; i < n; i++ {
        var t int
        var d string
        fmt.Scan(&t, &d)
        
        lr := 1
        if d == "L" {
            lr = -1
        }
        
        result := true
        l := t - ct
        for j := 0; j < l; j++ {
            switch dir[cd%4] {
                case "N": sy--
                case "S": sy++
                case "E": sx++
                case "W": sx--
            }
            if sy >= h || sx >= w || sy < 0 || sx < 0 || s[sy][sx] == '#' || s[sy][sx] == '*' {
                result = false
                break
            } else {
                runes := []rune(s[sy])
                runes[sx] = '*'
                s[sy] = string(runes)
            }
        }
        ct = t
        cd += lr
        
        if !result {
            break
        }
    }
    
    l := 100 - ct
    for i := 0; i < l; i++ {
        switch dir[cd%4] {
            case "N": sy--
            case "S": sy++
            case "E": sx++
            case "W": sx--
        }
        if sy >= h || sx >= w || sy < 0 || sx < 0 || s[sy][sx] == '#' || s[sy][sx] == '*' {
            break
        } else {
            runes := []rune(s[sy])
            runes[sx] = '*'
            s[sy] = string(runes)
        }
    }

    for i := 0; i < h; i++ {
        fmt.Println(s[i])
    }
}

実装はできましたが、ちょっと重複している部分があるので修正します。

package main
import "fmt"
func main(){
    var h, w, sy, sx, n int
    fmt.Scan(&h, &w, &sy, &sx, &n)
    
    s := make([]string, h)
    for i := 0; i < h; i++ {
        fmt.Scan(&s[i])
    }
    
    dir := []string{"N", "E", "S", "W"}
    ct := 0
    cd := 120
    
    // 初期の座標に印をつける
    runes := []rune(s[sy])
    runes[sx] = '*'
    s[sy] = string(runes)
    
    move := func(l int) bool {
        for i := 0; i < l; i++ {
            switch dir[cd%4] {
                case "N": sy--
                case "S": sy++
                case "E": sx++
                case "W": sx--
            }
            if sy >= h || sx >= w || sy < 0 || sx < 0 || s[sy][sx] == '#' || s[sy][sx] == '*' {
                return false
            } else {
                runes := []rune(s[sy])
                runes[sx] = '*'
                s[sy] = string(runes)
            }
        }
        return true
    }
    
    for i := 0; i < n; i++ {
        var t int
        var d string
        fmt.Scan(&t, &d)
        
        lr := 1
        if d == "L" {
            lr = -1
        }
        
        l := t - ct
        result := move(l)
        ct = t
        cd += lr
        
        if !result {
            break
        }
    }
    
    l := 100 - ct
    move(l)

    for i := 0; i < h; i++ {
        fmt.Println(s[i])
    }
}

move変数として関数化することですっきりしました👍

目指せSランク!!