結果

問題 No.936 Are
ユーザー maspymaspy
提出日時 2020-05-14 21:32:53
言語 Python3
(3.12.2 + numpy 1.26.4 + scipy 1.12.0)
結果
TLE  
実行時間 -
コード長 2,418 bytes
コンパイル時間 180 ms
コンパイル使用メモリ 11,008 KB
実行使用メモリ 13,084 KB
最終ジャッジ日時 2023-10-14 04:27:08
合計ジャッジ時間 9,418 ms
ジャッジサーバーID
(参考情報)
judge15 / judge14
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 23 ms
13,084 KB
testcase_01 TLE -
testcase_02 TLE -
testcase_03 -- -
testcase_04 -- -
testcase_05 -- -
testcase_06 -- -
testcase_07 -- -
testcase_08 -- -
testcase_09 -- -
testcase_10 -- -
testcase_11 -- -
testcase_12 -- -
testcase_13 -- -
testcase_14 -- -
testcase_15 -- -
testcase_16 -- -
testcase_17 -- -
testcase_18 -- -
testcase_19 -- -
testcase_20 -- -
testcase_21 -- -
testcase_22 -- -
testcase_23 -- -
testcase_24 -- -
権限があれば一括ダウンロードができます

ソースコード

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