Try T.M Engineer Blog

多摩市で生息するエンジニアが「アウトプットする事は大事だ」と思って始めたブログ

AtCoder Beginner Contest 306 B - Base 2

AtCoderをやり始めた。 全然問題が解けないので、復習する。

atcoder.jp

問題

$0$と$1$からなる長さ$64$の数列 $ A = (A_0,A_1,...,A_{63}) $ が与えられる。 $A_0 2^0 +A_1 2^1+...+A_{63}2^{63} $を求めよ。

制約

  • $ A_i は0または1 $

何も考えず書いたコード(間違い)

package main
 
import (
    "fmt"
    "strconv"
)
 
func main() {
    i2 := make([]int, 64)
    for i := 0; i < 64; i++ {
        fmt.Scanf("%d", &i2[i])
    }
 
    s2 := ""
    for i := 63; i >= 0; i-- {
        s2 += strconv.Itoa(i2[i])
    }
 
    ans, _ := strconv.ParseInt(s2, 2, 64)
 
    fmt.Println(ans)
}

間違いポイント

  • int64は、最大値が9223372036854775807。 $ 64の数列 A = (A_0,A_1,...,A_{63}) が全て1の値 $ は、18446744073709551615 のため、int64では入らない。
  • よって、strconv.ParseInt() も使えない。

正しい解

package main

import (
    "fmt"
    "math"
)

func main() {
    ui := make([]uint64, 64)
    for i := 0; i < 64; i++ {
        fmt.Scanf("%d", &ui[i])
    }

    var ans uint64
    for i, v := range ui {
        ans += v * uint64(math.Pow(2, float64(i)))
    }
    fmt.Println(ans)
}

ポイント

  • int64ではなくuint64を使う。
  • strconv.ParseInt()を使用せず、愚直に2進数から10進数へ変換する。