-FNS->

Bismと学ぶプログラミング ABC319

最終更新:

Bot(ページ名リンク)

- view
メンバー限定 登録/ログイン
今回はABC319の問題3問について解説します。
Bismは大会時は2問まで解けました。

A - Legendary Players

問題文要約

競技者10人の名前と今のレートのデータがもらえるので、名前を言ったらその人のレートを出力してね。

入力・出力例

入力

tourist

出力

3858
このコンテストが開始した時点において、touristさんのアルゴリズム部門のレーティングは3858です。

考えた解法

名前とレートが入った2次元配列を作り、そこからデータを取り出すプログラムを作ります。
S = input()

name = [["tourist", 3858], # [[名前1, レート1], [名前2, レート2], [ ... ]]
        ["ksun48", 3679],
        ["Benq", 3658],
        ["Um_nik", 3648],
        ["apiad", 3638],
        ["Stonefeang", 3630],
        ["ecnerwala", 3613],
        ["mnbvmar", 3555],
        ["newbiedmy", 3516],
        ["semiexp", 3481]]

for i in range(len(name)): # リストの回数繰り返す 名前が一致するか検索
    if S == name[i][0]: # もし文字列が今出したものと一致するなら
        print(name[i][1]) # その人のレートを出すよ
        break # 検索終わり

B - Measure

問題文要約

  • N = 与えられた整数
  • i = 0からNまでの整数のいずれか
  • j = 1〜9のNの約数
(1) iがN / jの倍数であるものが存在するとき
jのうち最小のものをsiとする。
※i=0の場合はjは全て当てはまるので、必ずs0=1となる。
(2) 存在しないとき
"-"をsiとする。

s0〜sNをつなげた文字列を出力してね。

入力・出力例

入力

12

出力

1-643-2-346-1

解法

iを0から順番に見ていきます。
jは1〜9の中のどれかなので、ループを回してもそこまで処理に時間はかかりません。
① S / jが割り切れる かつ ② i / (S / j)が割り切れる とき、(1)の処理を行うようにプログラムします。
ただし、この条件だとj=0のとき、Sを0で割るという処理はできませんので、強制的にs0=1とするような処理を行います。
S = int(input())

ans = ""
for i in range(S+1): # 0〜Nで順番にiを見ていく
    if i == 0: # i=0の場合
        ans += "1"
    else:
        count = 0
        for j in range(9):
            if S % (j+1) == 0 and i % (S // (j+1)) == 0:
                # %、//は割ったときの余り、商を出力したものだよ
                ans += str(j+1)
            elif j == 8:
                ans += "-"

print(ans)

C - False Hope

問題文要約

この問題はかなり複雑なので、今回は省略します。

入力・出力例

入力

3 1 9
2 5 6
2 7 1

出力

0.666666666666666666666666666667

解法

総当たりの処理を正確に書くことが問われる問題だと思います。
今回は、総当たりで処理をするにあたって必要な、「1〜9の文字を並び替えた全ての通りのリスト」を取得する方法が分からなかったため、解くことができませんでした。
それを行うプログラムは以下の通りです。
permutations(range(9))

こちらのプログラムを用いて、全体のプログラムを書いたのが以下の通りです。
from itertools import permutations

masu = []
for i in range(3): # 入力例の場合、masu=[3, 1, 9, 2, 5, 6, 2, 7, 1]
    masus = list(map(int, input().split()))
    for j in range(len(masus)):
        masu.append(masus[j])

# retsuは条件を満たすか調べる列一覧 
retsu =[(0,1,2),(3,4,5),(6,7,8),(0,3,6),(1,4,7),(2,5,8),(0,4,8),(2,4,6)]

# ordersは「1〜9の文字を並び替えた全ての通りのリスト」
orders = list(permutations(range(9)))

ans = 0
for order in orders:
    for a, b, c in retsu:
        count = 0 # breakを2回行うためのカウント
        for _ in range(3):
            # a番目とb番目に選ばれたマスに書かれている数字が一緒
               a番目よりc番目の方が遅い
               b番目よりc番目の方が遅い
            if masu[a]==masu[b] and order[a]<order[c] and order[b]<order[c]:
                ans += 1
                count += 1
                break
            a, b, c = b, c, a
        if count == 1:
            break

print(1 - (ans / 362880))
ウィキ募集バナー