22
7

More than 3 years have passed since last update.

Goで競技プログラミング

Last updated at Posted at 2019-12-07

IPFactory Advent Calender 2019 七日目

情報科学専門学校 1年 IPFactory所属 よーでん です。
最近はGolangで競技プログラミングをやってます。
「Goでやるならテンプレ作りなよ!」といわれたので、テンプレ作成ついでにメモとして書きます
理解して使うことが大事です。コピペは極力避けてください。

準備

main.go

package main

import (
    "bufio"
    "fmt"
    "math"
    "os"
    "strconv"
)

var sc = bufio.NewScanner(os.Stdin)

func main() {
    sc.Split(bufio.ScanWords)
}

事前準備。他にもパッケージを使いたい場合は適宜importしてもらえば良いです。

標準入力から読み込む

stringで一つ読み込む

hogehoge

func scanText() string {
    sc.Scan()
    return sc.Text()
}

func main() {
    sc.Split(bufio.ScanWords)

    a := scanText()
}

sc.Scanで標準入力から一つ受け取り、そのまま返している。

intで一つ読み込む

3

func scanInt() int {
    sc.Scan()
    a, err := strconv.Atoi(sc.Text())
    if err != nil {
        fmt.Println(err)
    }
    return a
}

func main() {
    sc.Split(bufio.ScanWords)

    n := scanInt()
}

strconv.Atoiでint型に変換。
デバッグしやすいようにerrの出力をいれている。

float64で一つ読み込む

3.14

func scanFloat() float64 {
    sc.Scan()
    a, err := strconv.ParseFloat(sc.Text(), 64)
    if err != nil {
        fmt.Println(err)
    }
    return a
}
func main() {
    sc.Split(bufio.ScanWords)

    n := scanFloat()
}

strconv.ParseFloatでfloat型に変換。

上記の関数を活用

hoge hoge
3 4
3.1 1.2

func scanText2() (string, string) {
    return scanText(), scanText()
}

func scanInt2() (int, int) {
    return scanInt(), scanInt()
}

func scanFloat2() (float64, float64) {
    return scanFloat(), scanFloat()
}

func main() {
    sc.Split(bufio.ScanWords)

    a, b := scanText2()
    c, d := scanInt2()
    e, f := scanFloat2()
}

こんな感じにしておけば、後々便利。かも。3とかも作ってもいいかもしれない。

複数受け取る

hoge hoge hoge hoge hoge
1 2 3 4 5
1.2 3.4 5.6 7.8 9.0

func scanTextSlice(n int) []string {
    a := make([]string, n)
    for i := 0; i < n; i++ {
        a[i] = scanText()
    }
    return a
}

func scanSlice(n int) []int {
    a := make([]int, n)
    for i := 0; i < n; i++ {
        a[i] = scanInt()
    }
    return a
}

func scanFloatSlice(n int) []float64 {
    a := make([]float64, n)
    for i := 0; i < n; i++ {
        a[i] = scanFloat()
    }
    return a
}

func main() {
    sc.Split(bufio.ScanWords)

    x := scanTextSlice(5)
    y := scanSlice(5)
    z := scanFloatSlice(5)
}

それぞれの型でループ回してるだけ。
mainからの引数は要素数。intはよく使うので名前を短く。

複数sliceを受け取る

x1 y1
x2 y2
x3 y3

func scanSlice2(n int) ([]int, []int) {
    a := make([]int, n)
    b := make([]int, n)
    for i := 0; i < n; i++ {
        a[i], b[i] = scanInt2()
    }
    return a, b
}

func scanFloatSlice2(n int) ([]float64, []float64) {
    a := make([]float64, n)
    b := make([]float64, n)
    for i := 0; i < n; i++ {
        a[i], b[i] = scanFloat2()
    }
    return a, b
}
func main() {
    sc.Split(bufio.ScanWords)

    x := scanSlice2()
    x := scanFloatSlice2()
}

問題ごとに数値の渡され方が違うため、こんな感じのも必要。

計算系

func abs(a int) int {
    if a > 0 {
        return a
    }
    return -a
}
func main() {
    a = abs(a)
}

↑引数の絶対値を返す。

func gcd(a, b int) int {
    if b == 0 {
        return a
    }
    return gcd(b, a%b)
}
func main() {
    a := gcd(b, c)
}

↑引数二つの最大公約数を返す。

func larger(a, b int) int {
    if a > b {
        return a
    }
    return b
}

func smaller(a, b int) int {
    if a < b {
        return a
    }
    return b
}

func main() {
    l := larger(a, b)
    s := smaller(a, b)
}

↑引数二つのうち、大きい方、小さい方を返す

func largest(a, b, c int) (lgst int) {
    if a > b {
        lgst = a
    } else {
        lgst = b
    }
    if c > lgst {
        lgst = c
    }
    return
}

func smallest(a, b, c int) (slst int) {
    if a < b {
        slst = a
    } else {
        slst = b
    }
    if c < slst {
        slst = c
    }
    return
}

func main() {
    l := lergest(a, b, c)
    s := smallest(a, b, c)
}

↑引数三つのうち、一番大きい、一番小さいのを返す

回答送信

func yesOrNo(b bool) string {
    if b {
        fmt.Println("Yes")
    }
    fmt.Println("No")
}

func yesorNO(b bool) string {
    if b {
        fmt.Println("YES")
    }
    fmt.Println("NO")
}
func main() {
    yesOrNo(true)
    yesOrNO(false)
}

Yes,NoもしくはYES,NOで答える。NO/Noで区別。問題ごとに丁度良いのを使う。

感想

テンプレ作成を始めてから間もないので、足りないもの、エラーの見落とし等があるかもしれません。
何か間違いや、おすすめの関数等ありましたら教えてください。

最後まで読んでいただき、ありがとうございました。

22
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
7