典型90【082 – Counting Numbers(★3)】をpython解説

Python

AtCoder の問題を解くために必要な実力を付けるために作られた「典型問題」を解いていく企画として、「典型90」があります。

今回は、その内、の82問目である「Counting Numbers(★3)」を解説していきたいと思います。
なにか、間違っているところなどありましたら、@EitaSugiまで、ご指導ご鞭撻の程、よろしくお願い致します!

問題名 【082 – Counting Numbers(★3)】

問題

問題文

何も書かれていない黒板があります。x=L, L+1, …, R の順に、以下の操作を行います。

  • 黒板に、整数 \(x\) を\(x\)回書く。
  • 全ての操作が終了した後、黒板に書かれている文字の個数を \(10^9 + 7\) で割った余りを求めてください。

ただし、数えるのは整数ではなく文字であることに注意してください。例えば、整数 15 は 2 個の文字として数えます。

考察

考えた内容の概要

与えられた範囲 L から R までの全ての整数を黒板に書く際、黒板に書かれる文字の総数を求める問題を考えます。ここで、文字の総数とは、各整数を構成する数字の個数の合計です。

考えたことの内容

まず、L から R までの各整数を順に考え、それぞれの整数が何桁かを確認します。次に、各桁数における整数の個数を求め、その桁数分だけ文字数が増加することを考慮します。これを全ての桁数について行い、合計することで答えを求めます。

実装した内容

L と R の桁数 min_len と max_len を求めます。min_len から max_len までの各桁数について、以下の処理を行います。

  • 現在の桁数における L と R の範囲を求めます。
  • その範囲にある整数の個数を求めます。
  • その範囲にある整数を全て書いたときの文字数を加算します。
  • 最後に答えを出力します。

コード

# 入力を受け取る
L, R = map(int, input().split())

# 定数として 10^9 + 7 を設定
mod = 10**9 + 7

# L と R の桁数を求める
min_len = len(str(L))
max_len = len(str(R))

# 答えを初期化
ans = 0

# 各桁数について考慮する
for dig in range(min_len, max_len + 1):
    # 現在の桁数における L と R の範囲を求める
    t_left = max(10**(dig - 1), L)
    t_right = min(10**dig - 1, R)
    
    # t_left と t_right の間にある整数の個数を求める
    between_num = t_right - t_left + 1
    
    # 現在の桁数における必要な文字数を加算する
    ans += between_num * (t_left + t_right) // 2 * dig
    
    # 答えを mod で割る
    ans %= mod

# 答えを出力する
print(ans)

解説

  • min_lenmax_len は、それぞれ L と R の桁数です。
  • t_leftt_right は、考慮している桁数における L と R の範囲です。
  • between_num は、t_leftt_right の間にある整数の個数です。
  • ans には、各桁数における必要な文字数を加算していきます。
  • このようにして、桁数ごとに計算を行い、最終的な答えを出力します。

まとめ

前の問題【081 – Friendly Group(★5)】
次の問題【】

コメント

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