結果

問題 No.936 Are
ユーザー maspymaspy
提出日時 2020-05-14 21:33:07
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 318 ms / 3,000 ms
コード長 2,418 bytes
コンパイル時間 306 ms
コンパイル使用メモリ 87,292 KB
実行使用メモリ 77,496 KB
最終ジャッジ日時 2023-10-14 04:29:13
合計ジャッジ時間 5,284 ms
ジャッジサーバーID
(参考情報)
judge12 / judge15
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 91 ms
76,316 KB
testcase_01 AC 201 ms
77,304 KB
testcase_02 AC 209 ms
77,408 KB
testcase_03 AC 97 ms
76,496 KB
testcase_04 AC 96 ms
76,492 KB
testcase_05 AC 94 ms
76,676 KB
testcase_06 AC 94 ms
76,596 KB
testcase_07 AC 93 ms
76,672 KB
testcase_08 AC 93 ms
76,312 KB
testcase_09 AC 94 ms
76,556 KB
testcase_10 AC 93 ms
76,620 KB
testcase_11 AC 96 ms
76,352 KB
testcase_12 AC 94 ms
76,568 KB
testcase_13 AC 129 ms
77,352 KB
testcase_14 AC 186 ms
77,148 KB
testcase_15 AC 131 ms
77,084 KB
testcase_16 AC 163 ms
77,484 KB
testcase_17 AC 152 ms
77,292 KB
testcase_18 AC 123 ms
77,276 KB
testcase_19 AC 204 ms
77,332 KB
testcase_20 AC 204 ms
77,332 KB
testcase_21 AC 318 ms
77,196 KB
testcase_22 AC 157 ms
77,484 KB
testcase_23 AC 208 ms
77,164 KB
testcase_24 AC 207 ms
77,496 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

import sys

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

MOD = 10**9 + 7

player_status = [(0, 1), (0, 2), (0, 3), (0, 4), (1, 1), (1, 2), (1, 3),
                 (1, 4), (2, 2), (2, 3), (2, 4), (3, 3), (3, 4), (4, 4)]

get_index = {x: i for i, x in enumerate(player_status)}

def encode(a, b, c, d):
    if a == b == 0:
        return -1
    if a > b:
        a, b = b, a
    if c > d:
        c, d = d, c
    i = get_index[(a, b)]
    j = get_index[(c, d)]
    return 14 * i + j

def division(i):
    import itertools
    a, b = player_status[i]
    ok_sum = [a + b] if a + b <= 5 else [a + b, a + b - 5]
    for c, d in itertools.product(range(5), repeat=2):
        if (c, d) in ((a, b), (b, a)):
            continue
        if c > d:
            c, d = d, c
        if c + d in ok_sum:
            j = get_index[(c, d)]
            if i != j:
                yield j

division_table = [list(division(n)) for n in range(14)]

def next_status(n):
    i, j = divmod(n, 14)
    a, b = player_status[i]
    c, d = player_status[j]
    # attack
    for _ in range(2):
        a, b = b, a
        for _ in range(2):
            c, d = d, c
            if a != 0 and c != 0:
                yield encode((a + c) % 5, d, a, b)
    # 分割
    for k in division_table[i]:
        yield 14 * j + k

win_able = [-1 in next_status(n) for n in range(196)]

def my_edge(n):
    # 相手の手番には、win_able positionをとらせないようにする
    return [i for i in next_status(n) if (not win_able[i])]

def opponent_edge(n):
    if win_able[n]:
        return []
    A = []
    B = []
    for i in next_status(n):
        if win_able[i]:
            A.append(i)
        else:
            B.append(i)
    if B:
        return B
    else:
        return A

E0 = []
for n in range(196):
    for m in my_edge(n):
        E0.append((n, m))

E1 = []
for n in range(196):
    for m in opponent_edge(n):
        E1.append((n, m))

N, K, a, b, c, d = map(int, read().split())

if N == 1:
    a,b,c,d = c,d,a,b

init = encode(a, b, c, d)

answer = 0
dp = [0] * 196
dp[init] = 1

for i in range(N, N+K):
    if i % 2 == 0:
        E = E0
    else:
        E = E1
    newdp = [0] * 196
    for n, m in E:
        if m == -1:
            answer += dp[n]
        else:
            newdp[m] += dp[n]
    dp = [x % MOD for x in newdp]
    answer %= MOD

print(answer)
0