AtCoder Beginner Contest 168

はい。
https://atcoder.jp/contests/abc168
ooo--- 862(-55) C問題まで。いまの実力で妥当な成績です。。。

A - ∴ (Therefore)

PyPy3

n=int(input())%10
print("hon" if n in (2,4,5,7,9) else "pon" if n in (0,1,6,8) else "bon")

書きやすい気がするのでこういう問題の時は in 配列で判定するのが好きです。

B - ... (Triple Dots)

PyPy3

k=int(input())
s=input()
print(s if len(s)<=k else s[:k]+"...")

スライス操作で解決します。

C - : (Colon)

PyPy3

import math
pi=3.1415926535897932
a,b,h,m=map(int,input().split())
ad=h*30+m*0.5
bd=m*6.0
x=min(abs(ad-bd),360.0-abs(ad-bd))
ans=a**2+b**2-(2*a*b*math.cos(math.radians(x)))
print(ans**0.5)

12WAしました。最も大きいミスは0時0分の時に離れている距離を0で決め打ちしてしまったことです。実際は針の長さの差の分離れています。何時何分かで針の角度を計算します。針の角度の差を180度以下で見るようにしました(180度なら針が直線、未満なら三角形が作られる)。2辺に挟まれる角の角度が分かると残りの辺の長さも求まるらしいです。求めます。針が一直線180度になる場合を特別に想定して長さがa+bとかはする必要が無いようです。そもそも180度になることがあるのか分かりませんが。

D - .. (Double Dots)

PyPy3

n,m=map(int,input().split())
w={}
for i in range(m):
    a,b=map(int,input().split())
    if a in w: w[a].add(b)
    else: w[a]=set([b])
    if b in w: w[b].add(a)
    else: w[b]=set([a])

d=[-1]*(n+1)
p=[set([]),set([1])]
d[1]=0
f=1
while 1:
    x=f%2
    y=(x+1)%2
    for i in p[x]:
        for j in w[i]:
            if d[j]==-1 or f<d[j]:
                d[j]=f
                p[y].add(j)
    p[x]=set([])
    if len(p[y])==0: break
    f+=1
print("Yes")
for i in range(2,n+1):
    for j in w[i]:
        if d[j]+1==d[i]:
            print(j)
            break

1から出発してそれぞれの頂点への最短移動を幅優先っぽく調べます。調べ終わったら1から出発してそれぞれの頂点へ最短何回目の移動で到着するかが調べ終わっています。
解の出力は2からNのそれぞれの頂点と隣接していて、かつ移動回数が1少ないものの部屋番号を出力します。移動回数が1少ない部屋番号は、いま調べている部屋から1へ最短で移動するために1回めに移動する部屋です。何を言っているか自分でも分かりません。

E問題以降はいつか。