ABC467を振り返ります
今回はABCまで3問解答でした。
A問題は、問題文をそのまま実装すると、少数の誤差で誤答(WA)になる問題です。私は見事にひっかかり、1回WAになりました。
D問題は数学(幾何)の問題です。考えた解答方針はあっていたのですが、直線の傾きの求め方が間違っていて、回答できずでした..。
さすがに直線の式を忘れているのはまずいよなあと思いつつも、数学を学んでいたのはだいぶ前なのでしょうがない、という気もします。
A - Obesity
少数の誤差でエラーが出そうだな...と思ってたら、やはり1回WAを出してしまいました。
H, W = map(int, input().split())
bmi = (W * 100 * 100) / (H * H)
if bmi >= 25:
print("Yes")
else:
print("No")
上記のコードで通ったのですが、割り算は使わずに以下の判定を行うほうが良さそうです。
W * 100 * 100 >= 25 * H * H
B - Keep the Change
・お釣りを受け取ったり受け取らなかったりする人
・必ずお釣りを受け取る人
の2パターンを計算して、最後に引き算をします。
N = int(input())
cash = 10000 # 所持金額
cash_y = 10000 # 必ずお釣りを受け取る人の所持金額
sum_a = 0
sum_back = 0
for i in range(N):
A, B, S = input().split()
A = int(A)
B = int(B)
if S == "keep":
# お釣りを受け取らない
cash = cash - B
else:
# お釣りを受け取っていた場合
cash = cash - A
# 必ずお釣りを受け取る人
cash_y = cash_y - A
print(cash_y - cash)
C - Adjacent Sums (easy)
DPで解きました。
Aを最初から見ていって、
・Aiに1を足さないケース
・Aiに1を足すケース
Biの条件を満たすそれぞれのケースでの最小値を求めていきます。
N, M = map(int, input().split())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
# dpの2次元配列
# [0]→1をたさないケース、[1]→2を足すケース
dp = [[0, 0] for i in range(N + 5)]
dp[0][0] = 0
dp[0][1] = 1
for i in range(N - 1):
candidate = []
# [i+1] に 1を足さないケース
if (A[i] + 0 + A[i + 1] + 0) % M == B[i]:
if dp[i][0] >= 0:
candidate.append(dp[i][0])
if (A[i] + 1 + A[i + 1] + 0) % M == B[i]:
if dp[i][1] >= 0:
candidate.append(dp[i][1])
if len(candidate) == 0:
# 条件を満たさないので、-1にしておく
dp[i + 1][0] = -1
else:
dp[i + 1][0] = min(candidate)
# [i+1] に 1を足すケース
candidate = []
if (A[i] + 0 + A[i + 1] + 1) % M == B[i]:
if dp[i][0] >= 0:
candidate.append(dp[i][0] + 1)
if (A[i] + 1 + A[i + 1] + 1) % M == B[i]:
if dp[i][1] >= 0:
candidate.append(dp[i][1] + 1)
if len(candidate) == 0:
dp[i + 1][1] = -1
else:
dp[i + 1][1] = min(candidate)
print(min(dp[N-1]))