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)