見出し画像

[ABC301 Python]パナソニックグループプログラミングコンテスト2023(AtCoder Beginner Contest 301)A~D問題Python解説

A問題

# 入力
N = int(input())
S = input()
# 髙橋君が勝った試合の数
Takahashi_win = S.count("T")
# 青木君が勝った試合の数
Aoki_win = S.count("A")
# 髙橋君が勝った数が青木君の勝った数より多ければ、
# 髙橋君が総合勝者
if Takahashi_win > Aoki_win:
    print("T")
# 青木君が勝った数が髙橋君の勝った数より多ければ、
# 青木君が総合勝者
elif Takahashi_win < Aoki_win:
    print("A")
# 勝った試合の数が同じであれば、
# 最後に勝った→先にその勝ち数に達した人ではないため、
# 最後に勝った人の相手を総合勝者とする
elif S[-1] == "T":
    print("A")
else:
    print("T")

勝利数が同じであれば、最後の試合を見て、
最後に勝った方が、総合勝者にならないと考えることができます。

B問題

# 入力
N = int(input())
A = list(map(int, input().split()))
# 答え
ans = []

for i in range(N-1):
    # ansにA[i]を代入
    ans.append(A[i])
    # 絶対値が1でない場合、その間の分をansに代入
    if A[i] - A[i+1] > 1:
        for j in reversed(range(A[i+1]+1, A[i])):
            ans.append(j)
    elif A[i+1] - A[i] > 1:
        for j in range(A[i]+1, A[i+1]):
            ans.append(j)

# 最後のA[-1]をansに代入
ans.append(A[-1])
# リスト型から空白区切りで代入
print(*ans)

元あるリストの間に値を挿入することを考えるのは難しいので、
新しくリストを作成したほうが考えやすいです。

C問題

# インポート
from collections import defaultdict
# 入力
S = list(input())
T = list(input())
# 置き換え可能なカード
atcoder = ["a", "t", "c", "o", "d", "e", "r"]
# Sの@の数
S_at = 0
# Sのカードをカード名ごとにカウント
S_d = defaultdict(int)
# 出現するカードの種類
cards = set()
# Sの全てのカードについて、
for s in S:
    # @の場合は、S_atをカウントアップ
    if s == "@":
        S_at += 1
    # それ以外の場合はカードの種類を保存し、
    # 種類ごとにS_dをカウントアップ
    else:
        cards.add(s)
        S_d[s] += 1
# Tについても同様に行う
T_at = 0
T_d = defaultdict(int)
for t in T:
    if t == "@":
        T_at += 1
    else:
        cards.add(t)
        T_d[t] += 1

# 出現した全てのカードについて
for card in cards:
    # SとTで出現回数が違うが、置き換え可能でなければ、
    # ゲームに勝つことはできない
    if card not in atcoder and S_d[card] != T_d[card]:
        print("No")
        exit()
    # あるカードの種類cardについて、
    # 数に相違がある場合はその分@で置き換える
    elif S_d[card] - T_d[card] > 1:
        T_at -= S_d[card] - T_d[card]
    elif T_d[card] - S_d[card] > 1:
        S_at -= T_d[card] - S_d[card]

# 残っている@の個数が0以上であれば、Yesと出力
if S_at >= 0 and T_at >= 0:
    print("Yes")
else:
    print("No")

いかさまによって、カードの順番は考えなくてよくなったので、
カードの種類ごとにカードの枚数を保存することで、回答することができます。

D問題

# 入力
S = input()
N = int(input())
# 最終的な出力
ans = 0
# ?を0にしたS
s = ""
# ?が1の時、2**(len(S)-i-1)加わることになるので、
# その候補
lis = []

for i in range(len(S)):
    # S[i]=1の時、これを置き換えることはできないので、
    # ansに追加する
    if S[i] == "1":
        ans += 2**(len(S)-i-1)
        s += "1"
    # S[i]=?の時、まずはsに0を追加し、
    # 候補をlisに追加する
    elif S[i] == "?":
        lis.append(2**(len(S)-i-1))
        s += "0"
    else:
        s += "0"
# ?を全て0にした時に、Nを超えてた場合は、
# N以下の値を作成できないので-1を出力する
if int(s, 2) > N:
    print(-1)
else:
    # lisの中から大きい順に、
    # ans+iがNを超えていなければ、
    # ansにプラスする
    for i in lis:
        if ans + i <= N:
            ans += i
    print(ans)

2023/05/14追記しました。

私たちは?を0にするか1にするかのみ操作することができます。
?をすべて0にした場合に既にNを超えていれば、
ここからは?の0を1にして増やしていく操作しかできないので、
-1を出力します。

後は、先頭から?の0を先頭から1にして、
Nを超えないように操作することで答えにたどり着けます。

この記事が気に入ったらサポートをしてみませんか?