【AtCoder】ABC372解説(Python)

AtCoder Beginner Contest 372の解説記事です。

目次

ABC372 A – delete .

問題

問題文の要約は以下の通りです。

問題の要約

文字列 \(S\) から. を全て削除した文字列を求めよ。

解説

replece関数を使用する。

解説

まず入力を受け取ります。

# 入力
S=input()

'.'''replaceします。

# '.' を '' にreplace
ans=S.replace('.', '')

答えを出力します。

# 出力
print(ans)

解答

# 入力
S=input()

# '.' を '' にreplace
ans=S.replace('.', '')

# 出力
print(ans)

まとめて書くと次のようになります。

print(input().replace('.',''))

ABC372 B – 3^A

問題

問題文の要約は以下の通りです。

問題の要約

正整数 \(M\) が与えられるので、\(3^{A_i}\) の和になるように \(M\) を分解せよ。

解説

考えられる\(3^{i}\) の形は \(3^{10}\), \(3^{9}\), \(3^{8}\), \(3^{7}\), \(3^{6}\), \(3^{5}\), \(3^{4}\), \(3^{3}\), \(3^{2}\), \(3^{1}\), \(3^{0}\) なので、大きい順に \(M\) から引いて答えを求める。

解説

まず入力を受け取り、答えの数列ansを用意します。

# 入力
M=int(input())

# 答えの数列
ans=[]

\(3^{10}\), \(3^{9}\), \(3^{8}\), \(3^{7}\), \(3^{6}\), \(3^{5}\), \(3^{4}\), \(3^{3}\), \(3^{2}\), \(3^{1}\), \(3^{0}\) のうち大きい順に \(M\) から引いて答えを求めます。

# M が 0 より大きい間処理を行う(0になったときにループを抜ける)
while M>0:
 # 10, 9, … , 0 の順に累乗を計算
  for i in range(10,-1,-1):
    # M が 3^i が以上の時
    if M>=3**i:
      # 答えの数列に追加
      ans.append(i)
      # M から 3^i を引く
      M-=3**i
      # for文を抜ける
      break

最後に答えの数列の長さと数列を出力します。

# 数列の長さ N を出力
print(len(ans))
# 答えの数列を出力
print(*ans)

解答

# 入力
M=int(input())

# 答えの数列
ans=[]

# M が 0 より大きい間処理を行う(0になったときにループを抜ける)
while M>0:
 # 10, 9, … , 0 の順に累乗を計算
  for i in range(10,-1,-1):
    # M が 3^i が以上の時
    if M>=3**i:
      # 答えの数列に追加
      ans.append(i)
      # M から 3^i を引く
      M-=3**i
      # for文を抜ける
      break

# 数列の長さ N を出力
print(len(ans))
# 答えの数列を出力
print(*ans)

ABC372 C – Count ABC Again

問題

問題文の要約は以下の通りです。

問題の要約

長さ \(N\) の文字列 \(S\) と \(Q\) 個のクエリが与えられるので処理せよ。
各クエリでは整数 \(X\) と文字 \(C\) が与えられるので、文字列 \(S\) の \(X\) 番目の文字を \(C\) に置き換えた後の文字列 \(S\) に連続部分文字列 ABC がいくつ含まれるかを出力せよ。

解説

クエリごとに1文字だけ置き換えるため、その周辺にある ABCの出現数のみ計算する。

解説

まず入力を受け取ります。

# 入力
N,Q=map(int,input().split())
S=input()

初期状態で文字列 \(S\) にABCがいくつ含まれているかを数えます。S.count('ABC') で文字列全体の ABCの数を数え、ans に格納します。

# 初期のABCの数
ans=S.count('ABC')

文字列 \(S\) をリストに変換します。文字列は変更不可(イミュータブル)なので、変更操作を行うためにリストに変換します。

# Sをリストに変換
s=list(S)

あるインデックスjから始まる 3 文字が ABCであるかを確認する関数を用意します。jの範囲が 0 からN−3までの間であることを確認し、連続する3文字が ABC かどうかを判定します。

# j,J+1,j+2文字目がABCになっているか判定
def check_ABC(j):
    # 範囲外のアクセスにならないように制御
    if 0 <=j and j+2< N:
        return s[j]=='A' and s[j+1]=='B' and s[j+2]=='C'
    return False

\(Q\) 個のクエリを処理します。入力を受け取り整数 \(X\) を0-indexedにします。

# Q個のクエリを処理
for _ in range(Q):
    # 入力を受け取り
    X,C=input().split()
    x=int(X)-1

変更前の文字列でのABCのカウント減算、文字を変更し、変更後の文字列でのABCのカウント加算して答えを出力します。

    # 変更前の文字列でのABCのカウント減算
    for i in range(x-2,x+1):
        if check_ABC(i):
            ans-=1

    # 文字を変更
    s[x] = C

    # 変更後の文字列でのABCのカウント加算
    for i in range(x-2,x+1):
        if check_ABC(i):
            ans+=1
    
    # 答えを出力
    print(ans)

解答

# 入力
N,Q=map(int,input().split())
S=input()

# 初期のABCの数
ans=S.count('ABC')
# Sをリストに変換
s=list(S)

# j,J+1,j+2文字目がABCになっているか判定
def check_ABC(j):
    # 範囲外のアクセスにならないように制御
    if 0 <=j and j+2< N:
        return s[j]=='A' and s[j+1]=='B' and s[j+2]=='C'
    return False

# Q個のクエリを処理
for _ in range(Q):
    # 入力を受け取り
    X,C=input().split()
    x=int(X)-1

    # 変更前の文字列でのABCのカウント減算
    for i in range(x-2,x+1):
        if check_ABC(i):
            ans-=1

    # 文字を変更
    s[x] = C

    # 変更後の文字列でのABCのカウント加算
    for i in range(x-2,x+1):
        if check_ABC(i):
            ans+=1
    
    # 答えを出力
    print(ans)
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次