AtCoder ABC168
2020-05-17(日)に行われたAtCoderBeginnerContest168の問題をA問題から順に考察も踏まえてまとめたものとなります.
前半ではABCまでの問題を扱います.
問題は引用して記載していますが,詳しくはコンテストページの方で確認してください.
コンテストページはこちら
公式解説PDF
A問題 ∴ (Therefore)
問題文
いろはちゃんは、人気の日本製ゲーム「ÅtCoder」で遊びたい猫のすぬけ君のために日本語を教えることにしました。
日本語で鉛筆を数えるときには、助数詞として数の後ろに「本」がつきます。この助数詞はどんな数につくかで異なる読み方をします。具体的には、$999$以下の正の整数$N$について、「$N$本」と言うときの「本」の読みは
・$N$の$1$の位が$2,4,5,7,9$のとき"hon"
・$N$の$1$の位が$0,1,6,8$のとき"pon"
・$N$の$1$の位が$3$のとき"bon"
です。
$N$が与えられるので、「$N$本」と言うときの「本」の読みを出力してください。
入力を数字で受け取って,$10$で割った余りが$1$の位になるので,その値で場合分け.
誤差だとは思うけど,少しでも早く提出するために,"hon"の出力をelse
にしました(条件式書くのが多少短くなる).
n = int(input())
k = n % 10
if k == 3:
print("bon")
elif k == 0 or k == 1 or k == 6 or k == 8:
print("pon")
else:
print("hon")
B問題 ... (Triple Dots)
問題文
英小文字からなる文字列$S$があります。
$S$の長さが$K$以下であれば、$S$をそのまま出力してください。
$S$の長さが$K$を上回っているならば、先頭$K$文字だけを切り出し、末尾に ... を付加して出力してください。
とりあえず,if文で$S$の長さと$K$を比較して,以下のときと上回っているときの処理を書けば終わりです.
pythonは文字列を配列みたいに扱えるので,for文使わずに書きました.
n = int(input())
s = input()
if len(s) <= n:
print(s)
else:
print(s[:n] + "...")
B問題解けたのがコンテスト開始から数分なので,このあたりまでは自分の理想とする時間で解けました.
C問題 : (Colon)
問題文
時針と分針の長さがそれぞれ$A$センチメートル、$B$センチメートルであるアナログ時計を考えます。
時針と分針それぞれの片方の端点は同じ定点に固定されており、この点を中心としてそれぞれの針は一定の角速度で時計回りに回転します。時針は$12$時間で、分針は$1$時間で$1$周します。
$0$時ちょうどに時針と分針は重なっていました。ちょうど$H$時$M$分になったとき、$2$本の針の固定されていない方の端点は何センチメートル離れているでしょうか。
2,3通り解き方が思いついたのですが,自分は余弦定理使って解きました.
求めたい値$D$は,
D = \sqrt{A^2 + B^2 - 2AB\cos \theta}
で求めることができるので,$\theta$を求めれば解けます.
時針と分針が,それぞれ0時から時計回りに針までの角度を,$\theta_A, \theta_B$とすると,
\theta_A = 30 \times H + 0.5 \times M \\
\theta_B = 6 \times M
となるので時針と分針のなす角$\theta$は,
\theta = \theta_A - \theta_B
で求めることができます.
ここで,$\theta$が$180$度より大きい場合や負になる場合が考えられますが,
\cos (360 - x) = \cos x \\
\cos (-x) = \cos x
となるため,特に問題なく余弦定理の計算をして長さを出すことができます.
import math
a, b, h, m = map(int, input().split())
x = 30 * h + m / 2 - 6 * m
d = math.sqrt(a**2 + b**2 - 2 * a * b * math.cos(math.radians(x)))
print(d)
他に思いついたのは,時針と分針の指し示す座標をそれぞれ$(A_x, A_y)=(A\cos\theta_1, A\sin\theta_1), (B_x, B_y)=(B\cos\theta_2, B\sin\theta_2)$とし,三平方の定理を用いることで求めたい$D$は,
D = \sqrt{(A_x - B_x)^2 + (A_y - B_y)^2}
で求めることができます.
余弦定理を使ったのは,答えが正の実数であり,正しい値との絶対誤差または相対誤差に制約があるため,math
の計算で誤差がどのくらい出るかわからなかったこともあり,極力使用回数が減らせる余弦定理で解きました.
前半はここまでとなります.
前半の最後まで読んでいただきありがとうございました.
後半はDEF問題の解説となります.
後半に続く.