2020-08-22
【Python】ABC176 解説
ABC176はリアルタイムでは参加できず.
バチャでやってみましたが4完2WAで撃沈. (参加しなくて良かったー)
以下, A~F問題の解説および解答例です. [2020/08/25- F問題を更新しました]
A - Takoyaki
math.ceil(a / b)
の代わりに (a + b - 1) // b
を用いるのは頻出テク.
N, X, T = map(int, input().split())
print(((N + X - 1) // X) * T)
B - Multiple of 9
N = input()
cnt = 0
for s in N:
cnt += int(s)
cnt %= 9
ans = 'Yes' if cnt % 9 == 0 else 'No'
print(ans)
C - Step
最近のC問題と比較すると易化傾向.
N = int(input())
A = list(map(int, input().split()))
height = A[0]
cnt = 0
for a in A:
if a < height:
cnt += (height - a)
else:
height = a
print(cnt)
D - Wizard in Maze
01BFSの典型問題.
公式解説にある下記の注意点について は, 考慮しなかったがACできた.
ただし、コスト1で追加された頂点がその後コスト0の移動のみで追加された際、2回同じ頂点が追加されることになるため、その点の実装に注意してください。
from collections import deque
H, W = map(int, input().split())
Ch, Cw = map(lambda x: int(x) - 1, input().split())
Dh, Dw = map(lambda x: int(x) - 1, input().split())
maze = [input() for _ in range(H)]
INF = 10 ** 12
path = [[INF] * W for _ in range(H)] # path: 各マスへの移動コスト
# walk:移動A, warp:移動B
walk = [(0, 1), (0, -1), (-1, 0), (1, 0)]
warp = [(i, j) for i in range(-2, 3) for j in range(-2, 3) if (i, j) not in [(0, 0)] + walk]
q = deque()
path[Ch][Cw] = 0
q.append((Ch, Cw, 0))
while q:
x, y, s = q.popleft()
for dx, dy in walk: # 移動A
nx = x + dx
ny = y + dy
if 0 <= nx < H and 0 <= ny < W and maze[nx][ny] == '.' and path[nx][ny] > s:
path[nx][ny] = s
q.appendleft((nx, ny, s)) # 移動Aの場合はコスト0. キューの先頭に追加する.
for dx, dy in warp: # 移動B
nx = x + dx
ny = y + dy
if 0 <= nx < H and 0 <= ny < W and maze[nx][ny] == '.' and path[nx][ny] > s + 1:
path[nx][ny] = s + 1
q.append((nx, ny, s + 1)) # 移動Bの場合はコスト1. キューの最後尾に追加する.
ans = path[Dh][Dw] if path[Dh][Dw] < INF else '-1'
print(ans)
E - Bomber
解説AC.
かなり難しく感 じたが, DifficultyはDよりも低いのか..
「ループが回未満」 or 「ループは回だが, 回目で必ず答えが見つかる」. したがって, .
この発想は初めて見た気がする. 勉強不足である.
import sys
H, W, M = map(int, input().split())
bomb = [tuple(map(lambda x: int(x) - 1, s.split())) for s in sys.stdin.readlines()]
X = [0] * H # X:各行の爆破対象の個数
Y = [0] * W # Y:各列の爆破対象の個数
for h, w in bomb:
X[h] += 1
Y[w] += 1
maxX = max(X)
maxY = max(Y)
R = [h for h, x in enumerate(X) if x == maxX] # R:爆破対象の数が最大となる行の番号
C = [w for w, y in enumerate(Y) if y == maxY] # C:爆破対象の数が最大となる列の番号
bomb = set(bomb)
for r in R:
for c in C:
if (r, c) not in bomb:
# (r, c)に爆破対象が存在しないとき, maxX + maxY が答えとなることが確定するため,
# 即座に探索を終了する. これによりルー プの回数は最大でもM+1回となる.
print(maxX + maxY)
exit()
print(maxX + maxY - 1)
F - Brave CHAIN
解説AC.
公式解説動画をほぼ写経しただけ.
pypy3で1997ms!! (2回実行して2回とも通ったので, まぐれではないはず)
from collections import deque
def upd(a, b, v):
global N # N の代わりに −1 を使用しても結果は同じだが, -1 だとなぜかTLEとなる.
dp[a][b] = max(dp[a][b], v)
dp[b][a] = max(dp[b][a], v)
dp[N][a] = max(dp[N][a], v)
dp[N][b] = max(dp[N][b], v)
dp[a][N] = max(dp[a][N], v)
dp[b][N] = max(dp[b][N], v)
dp[N][N] = max(dp[N][N], v)
N = int(input())
A = list(map(lambda x: int(x) - 1, input().split()))
INF = 1 << 32
dp = [[-INF] * (N + 1) for _ in range(N + 1)]
upd(A[0], A[1], 0)
base = 0
for i in range(2, 3 * N - 1, 3):
x, y, z = A[i], A[i + 1], A[i + 2]
if x == y == z: # x, y, z 3文字すべて等しいとき
base += 1
else:
q = deque()
for _ in range(3):
# a, b, x, y, z のうち, b, y, z を消すとき
for k in range(N):
v = dp[k][N]
if y == z:
v = max(v, dp[k][y] + 1)
q.append((k, x, v))
# a, b, x, y, z のうち, a, b, z を消すとき
v = max(dp[z][z] + 1, dp[N][N])
q.append((x, y, v))
# x, y, z をローテート
x, y, z = z, x, y
while q:
a, b, v = q.popleft()
upd(a, b, v)
l = A[-1]
ans = max(dp[N][N], dp[l][l] + 1)
print(ans + base)
関連記事最新記事
2021-05-09【Python】AtCoder - 30代社会人が始めて1年半で青色になりました
2021-04-12【Python】ABC198 解説
2021-03-27【Python】ABC197 解説
2021-03-20【Python】ABC196 解説
2021-03-13【Python】ABC195 パナソニックプログラミングコンテスト 解説