ABC Atcoder プログラミング

【ABC289】PythonでA~E問題を解く!(AtCoder Beginner Contest 289)

A - flip

愚直すぎますが、"0"を一旦関係ない"*"に置換して対比した後、"1"を"0"置換。その後、"*"を"1"に置換します。

replaceは複数の文字種を反転させるように置換ができないので、一旦別の文字に退避させる必要があります。

a = input()
print(a.replace("0","*").replace("1","0").replace("*","1"))

bashだと、「tr "変換対象文字列のセット" "変換後の文字列セット"」で一行で書ける様子。bashとかawkとか使えるようになりたいです。

tr 01 10

B - レ

漢文のレ点問題ですね。レ点が続く間はスタックし続けて、レ点がなくなったらスタックが空になるまでポップするという流れを書けばOKです。

N,M = map(int,input().split())
a = list(map(int,input().split()))
stack = []
result = []
for i in range(1,N+1):
  if i in a:
    stack.append(i)
  else:
    result.append(i)
    while stack:
      result.append(stack.pop())
print(*result)

C - Coverage

ビット全探索と、set型で集合を扱います。

ビット全探索で、全ての組み合わせに対して、和集合を取っていきます。その和集合が 1 から N を全て含むものかを判定して数を数えてきます。

N,M = map(int,input().split())
L = []
for _ in range(M):
  C = input()
  a = set(map(int,input().split()))
  L.append(a)
 
LS = set(range(1,N+1))
result = 0
for i in range(2 ** M):
  if i == 0:
    continue
  else:
    S = set()
    for j in range(M):
      if ((i >> j)& 1):
        #和集合
        S = S | L[j]
    if S == LS:
      result += 1
print(result)

D - Step Up Robot

かなり簡単な部類のDP(動的計画法)です。与えられる行動パターン数列Aも、上限が10と決まっているので、各ステップで愚直に全て試せば良いです。

N = int(input())
A = list(map(int,input().split()))
M = int(input())
B = list(map(int,input().split()))
X = int(input())
S = [0]*(X+1)
#モチがおいてあるところは-1として管理。
for b in B:
  S[b] = -1
#到達可能地点を1として扱う。今いる0段目は当然1
S[0] = 1

for i in range(1,X+1):
  #モチがおいてあるところはスルー
  if S[i] == -1:
    continue
  #いわゆる「もらうDP」。今いる地点に"来ることができるか?"を調べる。
  #ちなみに逆の「配るDP」は、今いる地点から"行くことができる"地点を調べ上げる方法。
  else:
    for a in A:
      if i-a >= 0:
        if S[i-a] == 1:
          S[i] = 1
          continue
if S[-1]:
  print("Yes")
else:
  print("No")

E - Swap Places

幅優先探索をもちいる。

from sys import stdin
from collections import deque
T = int(stdin.readline())

for _ in range(T):
    N, M = map(int, stdin.readline().split())
    C = list(map(int, stdin.readline().split()))
    #幅ノードの色と接続するノードを一括して辞書型で管理。正直あまり意味はない。
    G = {i+1: [C[i], set()] for i in range(N)}
    for _ in range(M):
        u, v = map(int, stdin.readline().split())
        G[u][-1].add(v)
        G[v][-1].add(u)
    visiteds = [[] for i in range(2)]
    # 状態の管理。-1は存在し得ない状態。それ以外はその状態になるためのコスト(操作回数)
    # 第1引数は高橋くんがいる地点。第2引数は青木くんがいる地点。
    result = [[-1]*(N+1) for _ in range(N+1)]
    # 初期状態。第1引数は高橋くんがいる1。第2引数は青木くんいる地点N。初期状態のコストは当然0
    result[1][N] = 0
    # 幅優先探索を用いる
    que = deque([(1, N)])

    while que:
        taka, aoki = que.popleft()
        for ntaka in G[taka][-1]:
            for naoki in G[aoki][-1]:
                if result[ntaka][naoki] != -1:
                    continue
                #色が異ならないとだめなので。
                if G[ntaka][0] == G[naoki][0]:
                    continue
                result[ntaka][naoki] = result[taka][aoki] + 1
                que.append((ntaka, naoki))
    print(result[N][1])
print(result)

-ABC, Atcoder, プログラミング