LoginSignup
0
1

More than 3 years have passed since last update.

AtCoderBeginnerContest164復習&まとめ(前半)

Last updated at Posted at 2020-04-29

AtCoder ABC164

2020-04-26(日)に行われたAtCoderBeginnerContest164の問題をA問題から順に考察も踏まえてまとめたものとなります.
前半ではABCまでの問題を扱います.
問題は引用して記載していますが,詳しくはコンテストページの方で確認してください.
コンテストページはこちら
公式解説PDF

A問題 Sheep and Wolves

問題文
羊が$S$匹、狼が$W$匹います。
狼の数が羊の数以上のとき、羊は狼に襲われてしまいます。
羊が狼に襲われるなら"unsafe"、襲われないなら"safe"を出力してください。

if文使えば終わりです.
他にあまり書くことないのですがあえて少し書くのであれば,本来襲われる条件が「以上」を使って書いてあるのでそのままコード書けばいいのですが,過去に比較演算子を「=<」と書いて事故った経験から,以上や以下を意識的に避けて書くことが多いです.正しくは「<=」です.
コロナで大学始まらず,SNSでは新入生の中で人狼などが流行っているので,人狼っぽい問題を作ったのか,元から好きなのかはわかりませんが,"Yes" or "No"の問題が個人的には好きです(スペルミスとか,大文字小文字とかすごく気を遣う).

abc164a.py
s, w = map(int, input().split())
if s > w:
    print("safe")
else:
    print("unsafe")

B問題 Battle

問題文
高橋君と青木君がモンスターを闘わせます。
高橋君のモンスターは体力が$A$で攻撃力が$B$です。
青木君のモンスターは体力が$C$で攻撃力が$D$です。
高橋君→青木君→高橋君→青木君→... の順に攻撃を行います。攻撃とは、相手のモンスターの体力の値を自分のモンスターの攻撃力のぶんだけ減らすことをいいます。このことをどちらかのモンスターの体力が0以下になるまで続けたとき、先に自分のモンスターの体力が0以下になった方の負け、そうでない方の勝ちです。
高橋君が勝つなら"Yes"、負けるなら"No"を出力してください。

とりあえず自分の提出したコードをまず載せます.

追記 : Pythonはwhileに()が不要なので,while True: と書くことができますが,自分は他の言語の癖で()を付けたまま書いてしまうことが多いです(汗)

abc164b.py
a, b, c, d = map(int, input().split())
while(True):
    c = c - b
    if c <= 0:
        print("Yes")
        break
    a = a - d
    if a <= 0:
        print("No")
        break

もちろん,$A$と$C$の体力がものすごく大きい場合があるなら,ループなんかしてられないけど,今回の問題の制約が100以下の整数だったから,迷わず問題文通りのコードを書きました.
Twitter上でいろいろ言われてるけど,後悔はしてないです(ミスってWAなること考えたら).
もちろん,以下のようなコードが頭をよぎったので,コンテスト終わった後に書き直しました.

abc164b.py
a, b, c, d = map(int, input().split())
if (c + b - 1) // b <= ( a + d - 1) // d:
    print("Yes")
else:
    print("No")

多少面倒なのは,小数点以下を切り上げる必要があるので,計算式が多少頭使うことになることだけど,このあたりは本番で書くならmathモジュールにあるceil使う方が安全かな

追記:@DaikiSuyama さんからコメントいただいた通り,ceil関数は誤差が生じる可能性があるようなので,使わない方が無難のようです.
式が複雑にならなくていいなと思い「安全かな」と書いてしまいましたが安全じゃありませんでした.
今回の問題は通ること確認してありますが,ABC046Cでは誤差によって通らなかったことを教えていただきました.
こういうコメントは,本当に参考になりますね.
@DaikiSuyama さん,ありがとうございました.
自分もきちんと過去問を解き直さないとですね.

abc164b.py
import math
a, b, c, d = map(int, input().split())
if math.ceil(c / b) <= math.ceil(a / d):
    print("Yes")
else:
    print("No")

C問題 gacha

問題文
くじ引きを$N$回行い、$i$回目には種類が文字列$S_i$で表される景品を手に入れました。
何種類の景品を手に入れましたか?

辞書型使えば終わりです.
このあたりは,自然言語処理で使いまくってるのでラッキーでした.
pythonはlen使えば,listだけでなく,dictの中にあるkeyの数返してくれるの本当に便利.
普段,単語の出現頻度数えるときは

word_dict = {}
for word in word_list:
    if word in word_dict
        word_dict[word] += 1
    else:
        word_dict[word] = 1

みたいに書くけど,今回の問題は回数使わないから楽に書けた.

追記:今回自分はdict使っていますが,公式の解説にもある通り,setやmapなどでも実装が可能です.

abc161c.py
n = int(input())
dict_s = {}
for i in range(0, n):
    s = input()
    dict_s[s] = 1
print(len(dict_s))

前半はここまでとなります.
後半はDEF問題の解説となります.
今回のコンテストはABCまで解いた後,行き詰まり,試行錯誤しましたが結局"AC"は出ずに終わってしまい,C問題までの短距離走の速さ比べになってしまい反省しています.
やっぱり,難しい問題を一問くらいは通して,徒競走から抜け出したいと思っています.
とりあえず前半の最後まで読んでいただきありがとうございました.
後半に続く

0
1
9

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1