【ABC329】競プロのA-C問題を40代サラリーマンがPython解説!初心者にもわかりやすく

abc329 AtCoder

こんにちは、こんぶちゃ(茶コーダー)です!

初心者視点から競プロAtCoderのABC329のA問題〜C問題の自身の解答と解答説明をしていきます。

こんな人にオススメしたい
  • 競技プログラミング初心者で、問題の解き方がわからない方
  • AtCoderの公式解説は読んだが、内容が理解できなかった方
  • Pythonでの解法を知りたい方

まだまだ学習の身ですので、最適コードではない部分も多々あるかと思いますが、その部分は同じ学習者として温かい気持ちで応援&ご助言頂けば嬉しいです。

では早速行ってみましょう!

今回の参加コンテスト(ABC329)

AtCoder Beginner Contest 329

A問題:Spread

A – Spread

問題文

英大文字からなる文字列 S が与えられます。S の各文字を空白で区切り、その順で 1 文字ずつ出力してください。

解答

# 文字列の各文字を空白で区切り、1文字ずつ出力
print(" ".join(input()))

解き方)

  1. input() を使ってユーザーから文字列を入力します。
  2. join メソッドを使って、文字列を空白で区切りながら結合します。
  3. 結合した文字列を print 関数で出力します。

B問題:Next

B – Next

問題(要約)

N 個の整数 A1​,A2​,…,AN が与えられます。 このうち最大でない整数の中で最大である整数を求めてください。ただし、この問題の制約下で答えは必ず存在します。

解答

n=input()
# 空白で区切られた整数を取得
# 重複を排除して昇順にソートし、最大でない整数の中で最大の値を取得して出力
print(sorted(list(set(map(int,input().split()))), reverse=True)[1])

解き方)

  1. input() を使ってユーザーから整数の個数 N を入力します(この部分では実際には使われていません)。
  2. input() を使って空白で区切られた整数を取得し、map を使って各要素を整数に変換します。
  3. set を使って重複を排除し、sorted を使って昇順にソートします。
  4. reverse=True を指定することで逆順(降順)になり、その中でインデックスが 1 の値(最大でない整数の最大値)を取得します。
  5. 結果を出力します。

C問題:Count xxx

C – Count xxx

問題(要約)

英小文字からなる文字列 S が与えられる。S の異なる1文字からなる部分文字列の数を求めよ。ただし、同じ文字の部分文字列は同じものとして扱う。

解答

from itertools import groupby

# 入力: 文字列の長さ n と文字列 S
n = int(input())
S = input()

# 文字の出現回数をタプルのリストに格納
substr_counts = [(sub, len(list(i))) for sub, i in groupby(S)]

# 出現回数で降順ソート
sorted_substr_counts = sorted(substr_counts, key=lambda x: x[1], reverse=True)

# 出現回数の最も多い異なる1文字からなる部分文字列を求める
words = set()
ans = 0
for sub, count in sorted_substr_counts:
    if sub not in words:
        ans += count
        words.add(sub)

# 結果を出力
print(ans)


解き方)

  1. 入力された文字列 S から連続する同じ文字の部分文字列をグループ化し、それぞれの文字とその出現回数のタプルを取得。
  2. 出現回数で降順にソート。
  3. ソートされた結果を元に、最も出現回数が多い異なる1文字からなる部分文字列を抽出。
  4. 出現回数を合計して、異なる1文字からなる部分文字列の総数を求めて出力。

感想

今週もC問題まで解けました!C問題で苦戦しましたが、回答に辿り着けました ^^

A、B問題はすぐに回答に辿り着けました。問題は比較的簡単でしたので、ここではコードをまとめて記載してみました。なんちゃって上級者気分です。ここだけの話ですが、コンテスト時は愚直にfor文回して解いています。

C問題は、初めは単語に対してfor文を回して、文字をリストに登録し、数を数えました。残念ながら実行制限時間超過。リストから集合に変えたりと試行錯誤を繰り返し、3回目の再実装で上記の答えに辿り着きました。

実装の正確性は上がってきましたが、実行時間を考えたアルゴリズム実装の練習が必要なので、精進して行きます。

Ratingは若干下がってしまいましたが、自身の最高点に近い551点なので、来週も頑張りたいと思います。

それでは、良い競プロライフを~!(*^▽^)/

コメント

タイトルとURLをコピーしました