あるエンジニアのAtCoder奮闘記

東京都港区にあるアミフィアブル株式会社のエンジニアが、AtCoderで解いた問題について振り返ったりしていく会社公認のブログです。

AtCoder ABC 126 F - XOR Matching (Go)

irisruneです。2本立てはタイトルも本文もごちゃごちゃするので1記事に1本がよさそうですね。

atcoder.jp

適当に試行すれば解法が出てくると聞いたのでやってみたらACできました。しかし出力時点でミスしてWAを積み重ねました。

package main

import (
    "fmt"
    "math"
    "strings"
)

func main() {
    var m, k int
    fmt.Scan(&m, &k)
    n := int(math.Pow(2.0, float64(m)))
    if n == 2 && k == 1 {
        fmt.Println(-1)
        return
    }
    if n <= k {
        fmt.Println(-1)
        return
    }

    ans := make([]int, 0)
    for i := 0; i < n; i++ {
        if i == k && k != 0 {
            continue
        }
        ans = append(ans, i)
    }
    if k != 0 {
        ans = append(ans, k)
    }

    for i := n - 1; i >= 0; i-- {
        if i == k && k != 0 {
            continue
        }
        ans = append(ans, i)
    }
    if k != 0 {
        ans = append(ans, k)
    }

    str := fmt.Sprintf("%v", ans)
    str = strings.Trim(str, "[]")
    fmt.Println(str)
}

解き方は大体解説の通りで、N\geq 2のとき、1 xor 2 xor ... xor 2^{N-1} = 0が成り立つことを用いれば条件を満たす数列を構築できます。

ただしN=1のときには先の等式は明らかに成り立たないので、

1 0

という入力に対し

1 0 1 0

などと出力してしまうとWAになってしまいます。その場合分けさえしておけば、記述が少し冗長になりがちな点を除いて躓くことはそれほどないと思います。

なお、1回のループで昇順の順列と降順の順列を同時に作って結合すると記述量が減ると思いますが、Go言語でやると降順の配列を作る処理で計算量がかかってしまいTLEしてしまいました。配列の先頭に要素を追加するときに配列長の計算量がかかるので厳しいですね。

雑記

  • 上記コードではやっていませんが、Go言語の入力処理のみを変えて過去に解いた問題を解き直してみました。

f:id:amifiable:20190522154228p:plain

f:id:amifiable:20190522154249p:plain

  • 格段に実行時間が短くなっていますね、入力がボトルネックになっていたのは確かなようです。
    • Juliaの立つ瀬がないですね…