くろたんく雑記帳

日常とか、わんちゃんとか、機械学習とか、競プロとか、

MENU

Python3で解く AtCoder Beginner Contest 152 D - Handstand 2

数値そのもので考えるというより、その数値の先頭とお尻の数値の組と逆にしたお尻と先頭の数値の組みがそれぞれ幾つ存在するのかっていうことを考える問題。こういう時はdefaultdict(というか常にdefaultdictでいいと思うけど)で行う。 dictでやる場合とdefaultdictでやる場合で何が違うのかを示してみる。

目次

概要

問題

  1. {\displaystyle n}が与えられる。
  2. {\displaystyle n}以下の正の整数の組{\displaystyle a, b}について以下の条件を満たすものはいくつある?
    1. {\displaystyle a}の一番右の桁の値が{\displaystyle b}の一番左の桁の値と一致する。
    2. {\displaystyle a}の一番左の桁の値が{\displaystyle b}の一番右の桁の値と一致する。
    3. 例えば{\displaystyle n=25}のとき、(1, 11)や(12, 21)は条件を満たしている。順列なので(11, 1)や(21, 12)は別カウントとして考える。

解くときに考えた内容

  • 一緒になる数値がどのパターンがあるかというのを考えると煩雑になりすぎる。
    • 例えば1, 11, 101・・・など。
  • {\displaystyle 1}以上{\displaystyle n}以下の正の整数の組{\displaystyle a, b}をすべてカウントする。
  • その組の中に、入れ替えた{\displaystyle n}以下の正の整数の組{\displaystyle b, a}がいくつあるかを探索する。
  • この時の{\displaystyle 1}以上{\displaystyle n}以下における、{\displaystyle a, b}の個数 {\displaystyle \times b, a}の個数の和は?
  • 実装上は数字を文字列として扱う方が一番右と一番左の値を取得するのが簡単。

keyの存在の有無によるdictとdefaultdictの違い

  • コードを見が方がわかりやすいが、dictではkeyが存在しない時に処理しようとするとエラーになるため、if文でkeyがない時の処理を書く必要がある。
  • defaultdictではその処理を書く必要がない。
    • 初期化としてvalueがどういったものなのかという型指定をする必要はある。
      例えばd = defaultdict(int)の様な形。
      リストをvalueとして用いたい場合はd = defaultdict(list)などとすると
      d.append(1)の様にすることも可能。

コード

defaultdictを用いた場合
from collections import defaultdict
n = int(input())
d = defaultdict(int)
for i in range(1, n+1):
    s = str(i)
    # 一番左の数字
    a = s[0]
    # 一番右の数字
    b = s[-1]
    d[a, b] += 1
ans = 0
d_items = list(d.items())
for (a, b), v in d_items:
    ans += v * d[b,a]
print(ans)
dictを用いた場合
n = int(input())
d = dict()
for i in range(1, n+1):
    s = str(i)
    # 一番左の数字
    a = s[0]
    # 一番右の数字
    b = s[-1]
    # keyない時の処理が必須
    if (a, b) not in d:
        d[(a, b)] = 0
    d[(a, b)] += 1
ans = 0
d_items = list(d.items())
for (a, b), v in d_items:
    if (b, a) not in d:
        d[(b, a)] = 0
    ans += v * d[(b, a)]
print(ans)