AtCoder に登録したら解くべき精選過去問 10 問を Go で解いてみた

けんちょんおすすめの10問をGoで解くのんっ!!!

第 1 問: ABC 086 A - Product (100 点)

標準入力にはfmt.Scanを使うのが一番手っ取り早いのん.
Goには三項演算子がないのんなー...

package main

import (
    "fmt"
)

func main() {
    var a, b int
    fmt.Scan(&a, &b)
    if a*b%2 == 1 {
        fmt.Println("Odd")
    } else {
        fmt.Println("Even")
    }
}

第 2 問: ABC 081 A - Placing Marbles (100 点)

varでの変数宣言は()でまとめられるのん

package main

import (
    "fmt"
)

func main() {
    var (
        s string
        i int
    )
    fmt.Scanln(&s)
    if s[0] == '1' {
        i++
    }
    if s[1] == '1' {
        i++
    }
    if s[2] == '1' {
        i++
    }
    fmt.Println(i)
}

第 3 問: ABC 081 B - Shift Only (200 点)

int型は宣言しただけだと0になるのん.
配列よりもスライスを使うほうが柔軟性があって良いのん.
ラベルをbreakすることでfor文をまとめて脱出できるのん! (戦争勃発)

package main

import (
    "fmt"
)

func main() {
    var n, count int
    fmt.Scan(&n)
    var a = make([]int, n)
    for i := 0; i < n; i++ {
        fmt.Scan(&a[i])
    }
LOOP:
    for {
        for i := 0; i < n; i++ {
            if a[i]%2 == 0 {
                a[i] /= 2
            } else {
                break LOOP
            }
        }
        count++
    }
    fmt.Println(count)
}

第 4 問: ABC 087 B - Coins (200 点)

package main

import (
    "fmt"
)

func main() {
    var a, b, c, x, count int
    fmt.Scan(&a, &b, &c, &x)
    for i := 0; i <= a; i++ {
        for j := 0; j <= b; j++ {
            for k := 0; k <= c; k++ {
                if 500*i+100*j+50*k == x {
                    count++
                }
            }
        }
    }
    fmt.Println(count)
}

第 5 問: ABC 083 B - Some Sums (200 点)

関数宣言は func 関数名(仮引数名 型) 返り値の型 なのん.

package main

import (
    "fmt"
)

func some(n int) int {
    var sum int
    for n > 0 {
        sum += n % 10
        n /= 10
    }
    return sum
}

func main() {
    var n, a, b, count int
    fmt.Scan(&n, &a, &b)
    for i := 1; i <= n; i++ {
        sum := some(i)
        if a <= sum && sum <= b {
            count += i
        }
    }
    fmt.Println(count)
}

第 6 問: ABC 088 B - Card Game for Two (200点)

Goはint, float64, stringのスライス型, sort.Interface型を満たした型なら, sortパッケージの関数が適用できるのん.
sort.IntSliceは[]int型にsort.Interface型を満たすメソッドとsort.Sort()が実装された型なのん.
sort.Reverse() はsort.Interface型を"ソートしたとき逆順になるようreverse型に変換"する関数なのん. これをsort.Sortすると逆順になるのんなー.

package main

import (
    "fmt"
    "sort"
)

func main() {
    var n, alice, bob int
    fmt.Scan(&n)
    a := make([]int, n)
    for i := range a {
        fmt.Scan(&a[i])
    }
    sort.Sort(sort.Reverse(sort.IntSlice(a)))
    for i := range a {
        if i%2 == 0 {
            alice += a[i]
            continue
        }
        bob += a[i]
    }
    fmt.Println(alice - bob)
}

第 7 問: ABC 085 B - Kagami Mochi (200点)

Goにもmap(ハッシュマップ, 連想配列)があるのんなー.

package main

import (
    "fmt"
)

func main() {
    var n int
    fmt.Scan(&n)
    d := make([]int, n)
    m := map[int]int{}
    for i := range d {
        fmt.Scan(&d[i])
        m[d[i]]++
    }
    fmt.Println(len(m))
}

第 8 問: ABC 085 C - Otoshidama (300点)

package main

import (
    "fmt"
)

func main() {
    var n, y int
    a, b, c := -1, -1, -1
    fmt.Scan(&n, &y)
    for i := 0; i <= n; i++ {
        for j := 0; i+j <= n; j++ {
            if 10000*i+5000*j+1000*(n-i-j) == y {
                a = i
                b = j
                c = n - i - j
            }
        }
    }
    fmt.Println(a, b, c)
}

第 9 問: ABC 049 C - Daydream (300点)

Goにはsubstrがないのん. pythonで言うスライスを使って切り取るのん.

package main

import (
    "fmt"
)

func Reverse(s string) string {
    rs := []rune(s)
    for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
        rs[i], rs[j] = rs[j], rs[i]
    }
    return string(rs)
}

func main() {
    var s string
    ss := []string{"maerd", "remaerd", "esare", "resare"}
    fmt.Scan(&s)
    s = Reverse(s)
    for i := 0; i < len(s); {
        b := false
        for j := 0; j < 4; j++ {
            if i+len(ss[j]) > len(s) {
                continue
            }
            if s[i:i+len(ss[j])] == ss[j] {
                b = true
                i += len(ss[j])
            }
        }
        if b == false {
            fmt.Println("NO")
            return
        }
    }
    fmt.Println("YES")
}

第10問: ABC 086 C - Traveling (300点)

mathパッケージに絶対値を取得する関数Absがあるのん. ただしこれは引数にfloat64型をとるのでint型を使っていたら型変換が必要なのん.

package main

import (
    "fmt"
    "math"
)

func main() {
    var n int
    fmt.Scan(&n)
    t, x, y := make([]int, n+1), make([]int, n+1), make([]int, n+1)
    for i := 1; i <= n; i++ {
        fmt.Scan(&t[i], &x[i], &y[i])
    }
    for i := 1; i <= n; i++ {
        a := t[i] - t[i-1]
        b := math.Abs(float64(x[i]-x[i-1])) + math.Abs(float64(y[i]-y[i-1]))
        if a < int(b) || int(b)%2 != a%2 {
            fmt.Println("No")
            return
        }
    }
    fmt.Println("Yes")
}

まとめ

Goは癖が強いので競技プログラミングをするときには注意が必要なのん. でも実行速度が速いからなかなか戦えると思っているのん.

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.