LoginSignup
3
3

More than 3 years have passed since last update.

AtCoder Beginner Contest 147 参戦記

Last updated at Posted at 2019-12-08

AtCoder Beginner Contest 147 参戦記

ABC147A - Blackjack

2分半で突破. 書くだけ.

A1, A2, A3 = map(int, input().split())

if sum([A1, A2, A3]) >= 22:
  print('bust')
else:
  print('win')

ABC147B - Palindrome-philia

2分で突破. 書くだけ.

S = input()

result = 0
for i in range(len(S) // 2):
  if S[i] != S[-(i + 1)]:
    result += 1
print(result)

ABC147D - Xor Sum 4

46分くらい?で突破. Cを提出したら WA3 で諦めてこっちに取り掛かったのでよく分からず. ビットごとに累積 XOR をするだけ. だけって言ってもコーディングは中々大変. Python で書いたら TLE になったので、Go で書き直した. % 1000000007 がある問題はできるだけ Python で書きたいのにね.

Ai のあるビットが0の場合、Ai+1~ANのあるビットが1の個数をかける、Ai のあるビットが1の場合、Ai+1~ANのあるビットが0の個数をかけることによって、個数の累積和が取ってあれば内側のシグマはループせずに計算できる. 制約より0≤Ai<260なので、ビットごとに60回処理すれば良い.

package main

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

func main() {
    const m = 1000000007

    N := readInt()
    A := make([]int, N)
    for i := 0; i < N; i++ {
        A[i] = readInt()
    }

    result := 0
    a := make([]int, N)
    bs := make([]int, N)
    for b := 0; b < 60; b++ {
        for i := 0; i < N; i++ {
            a[i] = (A[i] >> uint(b)) & 1
        }

        bs[N-1] = a[N-1]
        for i := N - 2; i > -1; i-- {
            bs[i] = bs[i+1] + a[i]
        }

        t := 0
        for i := 0; i < N-1; i++ {
            if a[i] == 0 {
                t += bs[i+1]
            } else {
                t += (N - (i + 1)) - bs[i+1]
            }
        }
        t %= m

        v := (1 << uint(b)) % m
        result += (t * v) % m
        result %= m
    }
    fmt.Println(result)
}

const (
    ioBufferSize = 1 * 1024 * 1024 // 1 MB
)

var stdinScanner = func() *bufio.Scanner {
    result := bufio.NewScanner(os.Stdin)
    result.Buffer(make([]byte, ioBufferSize), ioBufferSize)
    result.Split(bufio.ScanWords)
    return result
}()

func readString() string {
    stdinScanner.Scan()
    return stdinScanner.Text()
}

func readInt() int {
    result, err := strconv.Atoi(readString())
    if err != nil {
        panic(err)
    }
    return result
}

追記: 結局この計算は Ai のすべての組み合わせ(Ai 自身同士は含まない)の XOR の合計なので、Ai のあるビットの立っている数の合計を c とすると、Ai のあるビットが0であった場合により計算結果に立つビットの数は c、Ai のあるビットが1であった場合により計算結果に立つビットの数は N - c になるので、あるビットに関する計算結果は c * (N -c) のビットシフトした値になる. 結果として以下の計算で解ける.

N = int(input())
A = list(map(int, input().split()))

result = 0
for bit in range(60):
    m = 1 << bit
    c = sum(a & m for a in A) >> bit
    result += (c * (N - c)) << bit
    result %= 1000000007
print(result)

ABC147C - HonestOrUnkind2

35分くらい?で突破. N≤15 なので、全組み合わせやっても 215 でしかなく、やるだけ. だけって言ってもコーディングは中々大変. 最初 for i in range(1, 2 ** N):for i in range(1, 2 ** N - 1): になってて WA3 だった. D問題が終わった後に見直していたら気づいた.

N人の「正直者」、「不親切な人」のすべての組み合わせを生成し、正直者の証言が組み合わせに矛盾していないか確認する. 矛盾していない組み合わせの正直者の最大数が解答.
組み合わせは bit で表現している. Nビット用意し、1が立っていると正直者、0だと不親切な人. この組み合わせ状況と正直者の証言が矛盾しないか確認する.

N = int(input())

evidences = [[] for _ in range(N)]
for i in range(N):
    A = int(input())
    for _ in range(A):
        x, y = map(int, input().split())
        evidences[i].append((x - 1, y))

result = 0
for i in range(1, 2 ** N):
    consistent = True
    for j in range(N):
        if (i >> j) & 1 == 0:
            continue
        for x, y in evidences[j]:
            if (i >> x) & 1 != y:
                consistent = False
                break
        if not consistent:
            break
    if consistent:
        result = max(result, bin(i)[2:].count('1'))
print(result)

ABC147E - Balanced Path

突破できず. 貪欲法では駄目なのは分かるけど、じゃあどうすればいいというのが思いつかなかった. 3次元DPかー(解説を見て). 解説読んでもさっぱりわかりませんね.

3
3
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
3
3