Official
B - 元気な応援メッセージ / Cheerful Support Message Editorial by admin
Gemini 3.0 Flash概要
\(N\) 個の文字列が与えられ、それぞれの文字列の中に含まれる感嘆符 ! の個数を数えます。その個数が \(K\) 個以上である文字列(元気な応援メッセージ)がいくつあるかを求める問題です。
考察
この問題を解くためには、各メッセージ \(S_i\) に対して「! が何個含まれているか」を正確に判定する必要があります。
- 文字列の走査: 1つのメッセージの長さは最大で \(10^3\) です。文字列を先頭から 1 文字ずつ確認して
!をカウントしても十分間に合います。 - 制約の確認: メッセージの総数は \(N \le 10^4\)、各メッセージの長さは \(|S_i| \le 10^3\) です。最悪の場合、全体で \(10^4 \times 10^3 = 10^7\) 文字を処理することになります。Python で処理する場合、標準的な
input()を繰り返すよりも、一括で読み込むなどの工夫をするとより安全です。 - 特殊なケース: メッセージの最大長が \(1000\) であるため、もし \(K > 1000\) であれば、どのメッセージも条件を満たすことはありません。この場合、即座に
0と出力しても正解となります。
アルゴリズム
以下の手順で解を求めます。
- 入力の取得: \(N, K\) と \(N\) 個の文字列 \(S_1, S_2, \dots, S_N\) を読み込みます。
- カウント処理: 各 \(S_i\) について、以下のいずれかの方法で
!の個数を調べます。- 文字列の
count('!')メソッドを使う。 - 文字列を
!で分割(split)し、分割されたリストの要素数から計算する。s.split('!')で得られるリストの長さが \(m\) のとき、含まれる!の個数は \(m - 1\) 個です。- したがって、
m - 1 >= kすなわちm > kであれば「元気な応援メッセージ」です。
- 文字列の
- 集計: 条件を満たすメッセージが見つかるたびに、答えとなる変数
energetic_countを \(1\) ずつ増やします。 - 出力: 最終的な
energetic_countを出力します。
計算量
- 時間計算量: \(O(\sum |S_i|)\)
- 全てのメッセージの全文字を一度ずつ走査するため、文字数の総和に比例した時間がかかります。最大で \(10^7\) 文字程度であり、実行時間制限内に十分収まります。
- 空間計算量: \(O(\sum |S_i|)\)
- 入力された全ての文字列をメモリ上に保持する場合の計算量です。
実装のポイント
効率的な入力:
sys.stdin.read().split()を使うことで、空白や改行で区切られた入力を一括でリストとして取得できます。これにより、大量の入力データに対しても高速に処理を開始できます。文字数カウントの工夫: Python の
split('!')メソッドは内部が C 言語で実装されているため非常に高速です。リストの長さを比較するだけで条件判定ができるため、シンプルかつ効率的な実装になります。ソースコード
import sys
def main():
# Read all input from standard input and split into tokens by whitespace.
# This approach is efficient in Python and handles N, K, and all messages S_i.
# Since S_i only contains letters, digits, and '!', it does not contain whitespace.
data = sys.stdin.read().split()
if not data:
return
# N: number of messages, K: minimum number of exclamation marks required.
n = int(data[0])
k = int(data[1])
# The problem constraints state that each message S_i has a maximum length of 1000.
# If the threshold K is greater than 1000, no message can possibly be "energetic".
if k > 1000:
print(0)
return
# We count "energetic" messages using a different approach from .count().
# By splitting the string s by the exclamation mark '!', the resulting list
# of segments will have a length equal to (number of '!' characters) + 1.
# Therefore, s.count('!') >= k is equivalent to len(s.split('!')) > k.
energetic_count = 0
# Messages are stored in the data list starting from index 2 up to index 2+n.
for i in range(2, 2 + n):
if i < len(data):
# Applying the split-based counting logic
if len(data[i].split('!')) > k:
energetic_count += 1
# Print the final count of energetic messages.
print(energetic_count)
if __name__ == '__main__':
main()
この解説は gemini-3-flash-preview によって生成されました。
posted:
last update: