問題
D – 大ジャンプ
回答
90点回答 深さ優先探索
\(4^8 = 65534 \) 通りであれば全探索ができる。
N, D = map(int, input().split())
X, Y = map(int, input().split())
def main(N, D, X, Y):
# 割り切れない場合到達できない。
if (X % D != 0 or Y % D != 0):
return 0
# 距離を標準化。
x_std = X / D
y_std = Y / D
def dfs(now_x, now_y, count):
if count == N:
if now_x == x_std and now_y == y_std:
return 1
else:
return 0
result = 0
count += 1
search_dires = [(1, 0), (-1, 0), (0, 1), (0, -1)]
for search_dire in search_dires:
next_x = now_x + search_dire[0]
next_y = now_y + search_dire[1]
result += dfs(next_x, next_y, count)
return result
result = dfs(0, 0, 0)
return result / (4 ** N)
if __name__ == '__main__':
print(main(N, D, X, Y))
100点 メモ化再帰
@functools.lru_cache(user_function) でメモ化再帰を行います。
from functools import lru_cache
N, D = map(int, input().split())
X, Y = map(int, input().split())
def main(N, D, X, Y):
# 割り切れない場合到達できない。
if (X % D != 0 or Y % D != 0):
return .0
# 距離を標準化。
x_std = X / D
y_std = Y / D
@lru_cache(maxsize=2**20)
def dfs(count, now_x, now_y):
if count == N:
if now_x == x_std and now_y == y_std:
return 1
else:
return 0
result = 0
count += 1
search_dires = [(1, 0), (-1, 0), (0, 1), (0, -1)]
for search_dire in search_dires:
next_x = now_x + search_dire[0]
next_y = now_y + search_dire[1]
result += dfs(count, next_x, next_y)
return result
result = dfs(0, 0, 0)
return result / (4 ** N)
if __name__ == '__main__':
print(main(N, D, X, Y))
101点回答
REが解決できず保留。
from math import factorial
N, D = map(int, input().split())
X, Y = map(int, input().split())
def comb(n, r):
try:
comb = factorial(n) / factorial(r) / factorial(n - r)
except ValueError:
print('error', n, r)
return int(comb)
def main(N, D, X, Y):
# 割り切れない場合到達できない。
if (X % D != 0 or Y % D != 0):
return .0
# 距離を標準化。
x_std = X / D
y_std = Y / D
count = 0
for move_hor in range(0, N+1):
move_ver = N - move_hor
if (move_hor + x_std) % 2 != 0 or (move_ver + y_std) % 2 != 0:
continue
# 左右に動く
comb_move_hor = comb(N, move_hor)
move_right = (move_hor + x_std) // 2
if move_hor < move_right:
continue
comb_move_right = comb(move_hor, move_right)
# 上下に動く
move_up = (move_ver + y_std) // 2
if move_ver < move_up:
continue
comb_move_up = comb(move_ver, move_up)
count += comb_move_hor * comb_move_right * comb_move_up
return count / (4 ** N)
if __name__ == '__main__':
print(main(N, D, X, Y))