[ABC289 Python]Sky株式会社プログラミングコンテスト2023(AtCoder Beginner Contest 289)A~D問題Python解説
A問題
S = list(input())
for i in range(len(S)):
if S[i] == "0":
S[i] = "1"
else:
S[i] = "0"
print("".join(S))
文字の入れ替えを問題文のとおりで行います。
入力をリスト型で行い、リスト型を最後に文字列型に直して出力します。
B問題
N, M = map(int, input().split())
a = list(map(int, input().split()))
ans = []
remoji = []
for i in range(1, N+1):
remoji.append(i)
if i not in a:
ans += sorted(remoji,reverse=True)
remoji = []
print(*ans)
漢文のレ点ですので、
レ点の両端にある文字が入れ替わります。
ですのでレ点が繋がっている間はリストremojiに保存しておき、
レ点が切れたタイミングでリバースするというスクリプトを書くといいでしょう。
まずはremojiに文字を入れ、
レ点が切れたタイミングで、reversed(remoji, reverse=True)
で逆順にソートします。
そしてremojiを答えとなるansに入れremojiを初期化します。
C問題
import itertools
N, M = map(int, input().split())
a_list = []
for i in range(M):
C = input()
a = list(map(int, input().split()))
a_list.append(a)
x_set = set([_ for _ in range(1, N+1)])
ans = 0
for i in range(1, M+1):
for j in itertools.combinations(a_list, i):
comb = set(itertools.chain.from_iterable(j))
if comb == x_set:
ans += 1
print(ans)
基本的には問題文のとおり、
集合をすべて試すという方法をとる全探索で解いていきます。
M個の集合を全てa_listに入れておきます。
次に条件を示す、「選んだ集合の中にxを含む集合が少なくとも1個存在する」というのがset()を用いて作ることができます。
後はitertools.combinaiotns()で組み合わせをすべて試します。
集合を平坦化するために以下も使います。
全ての集合の組み合わせに対して、
条件を満たす組み合わせをカウントし最後に出力します。
D問題
N = int(input())
A = list(map(int, input().split()))
M = int(input())
B = list(map(int, input().split()))
X = int(input())
rice_cake = [False for _ in range(X+1)]
for b in B:
rice_cake[b] = True
dp = [False for _ in range(X+1)]
dp[0] = True
for i in range(1, X+1):
if not rice_cake[i]:
for a in A:
if i-a >= 0 and dp[i-a]:
dp[i] = True
if dp[X]:
print("Yes")
else:
print("No")
2023/02/15追記しました。
DPの問題です。
DPについてわからない方は下の記事などを見ていただければと思います。
0~X段目についてその段に上ることができればTrue
上ることができないのであればFalse
とします。
答えはX段目に上ることができるかですので、
上記のDPで解くことができます。
その段に上ることができる条件は、
ロボットが1回に上ることができる段数をAiとすると、
その段からAi分前に上ることができているかを調べればわかります。
ですので条件としては、
餅がある箇所についてはその箇所から移動することができませんのでFalseとし、それ以外の箇所については、リストAの全てのAiに対してその箇所からAi下の箇所が登れていればTrueにします。