ABC 025 B問題 「双子のスイカ割り」(Python)

B - 双子とスイカ割り

愚直に書いて以下でACだった。

N,A,B = map(int, input().split())
moves = list(list(input().split()) for _ in range(N))
s = 0
for move in moves:
    move[1] = int(move[1])
    if move[0] == "West":
        if move[1] < A:
            s += A
        elif move[1] > B:
            s += B
        else:
            s += move[1]
    if move[0] == "East":
        if move[1] < A:
            s -= A
        elif move[1] > B:
            s -= B
        else:
            s -= move[1]
if s < 0:
    print("East", int(pow(s**2, 1/2)))
elif s == 0:
    print(0)
else:
    print("West", s)

手直し

minefyさんのコードを参考にさせてもらった。

「West」「East」の判定

方角を判定することで進む距離の正負を変更させたいわけだが、そのまま書けば

if move[0] == "West":
  hoge
if move[0] == "East":
  hoge

となるが、もっと簡単にかける。

(2*(方角=="West")-1)*進んだ距離

とすることで正負を方角によって変更できる。PythonではTrue=1、False=0となるので(2*(方角=="West")-1)でスッキリかける。

A,Bとの大小関係の判定

この問題では進んだ距離がAより小さい場合やBより大きい場合は、進んだ距離をA,Bに置き換えて加算する仕様。

if move[1] < A:
  s += A
elif move[1] > B:
  s += B
else:
  s += move[1]

これも、進んだ距離とA,Bとの大小関係をmin()、max()を使うことで表現できる。

進んだ距離をmとすると、mがBより小さい場合はmを、大きい場合はBの値を使用するようにすればよいのだから

min(m, B)

同様に、mがAより小さい場合はAを、大きい場合はmを使用するには

max(A,m)

とすればよい。

両方の条件を満たすようにすると

min(max(m,A),B)

で表現できる。

最終的

N,A,B = map(int, input().split())
moves = list(list(input().split()) for _ in range(N))

s = 0
for m in moves:
    m[1] = int(m[1])
    s += (2*(m[0]=="West")-1) * min(max(m[1],A),B)
    
if s < 0:
    print("East", -s)
elif s == 0:
    print(0)
else:
    print("West", s)