結果
| 問題 |
No.1153 ねこちゃんゲーム
|
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 2025-05-14 13:24:59 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 3,913 bytes |
| コンパイル時間 | 689 ms |
| コンパイル使用メモリ | 82,372 KB |
| 実行使用メモリ | 848,836 KB |
| 最終ジャッジ日時 | 2025-05-14 13:26:08 |
| 合計ジャッジ時間 | 15,875 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | TLE * 1 MLE * 5 -- * 34 |
ソースコード
import sys
# Increase recursion limit for deep recursive calls on paths
sys.setrecursionlimit(4 * 10**5)
memo = {} # Memoization table for Grundy values
adj = [] # Adjacency list for the tree
def compute_grundy(u, visited_fset):
"""
Calculates the Grundy value for a cat.
u: current vertex of the cat (1-indexed)
visited_fset: frozenset of vertices visited by this cat so far (includes u)
"""
state = (u, visited_fset)
if state in memo:
return memo[state]
seen_grundy_values_of_options = set()
# adj is 0-indexed, u is 1-indexed
for neighbor_node in adj[u - 1]:
if neighbor_node not in visited_fset:
# Move cat to neighbor_node
# New visited set includes the neighbor_node
new_visited_fset = visited_fset.union({neighbor_node})
seen_grundy_values_of_options.add(compute_grundy(neighbor_node, new_visited_fset))
# Calculate mex of the set of Grundy values of options
g = 0
while g in seen_grundy_values_of_options:
g += 1
memo[state] = g
return g
def solve():
global adj # Allow modification of global adj
N, M = map(int, sys.stdin.readline().split())
initial_cat_positions = list(map(int, sys.stdin.readline().split()))
adj = [[] for _ in range(N)]
for _ in range(N - 1):
u_edge, v_edge = map(int, sys.stdin.readline().split())
adj[u_edge - 1].append(v_edge)
adj[v_edge - 1].append(u_edge)
# Handle N=1 case: No moves possible
if N == 1:
print("-1 -1")
return
cat_initial_grundy_values = []
for i in range(M):
cat_start_node = initial_cat_positions[i]
initial_visited_fset = frozenset({cat_start_node})
val = compute_grundy(cat_start_node, initial_visited_fset)
cat_initial_grundy_values.append(val)
nim_sum = 0
for g_val in cat_initial_grundy_values:
nim_sum ^= g_val
if nim_sum == 0:
# QiQi (second player) wins
print("-1 -1")
else:
# XiaXia (first player) wins, find an optimal move
for i in range(M): # Iterate through each cat
cat_id_1_indexed = i + 1
current_pos = initial_cat_positions[i]
# Grundy value of the game if this cat i was removed (or its subgame's G was 0)
# is nim_sum XOR cat_initial_grundy_values[i]
# We want the new Grundy value of cat i's subgame (g_prime_k) to be this value.
target_grundy_for_cat_after_move = nim_sum ^ cat_initial_grundy_values[i]
initial_visited_fset_for_this_cat = frozenset({current_pos})
# Iterate over possible moves for this cat
# adj is 0-indexed, current_pos is 1-indexed
for neighbor_node in adj[current_pos - 1]:
# A move to neighbor_node is valid if neighbor_node is not in initial_visited_fset_for_this_cat.
# Since initial_visited_fset_for_this_cat only contains current_pos, any neighbor is valid for the first move (as long as N > 1).
# Calculate Grundy value of cat i's subgame AFTER moving to neighbor_node
visited_fset_after_move = initial_visited_fset_for_this_cat.union({neighbor_node})
grundy_of_cat_after_move = compute_grundy(neighbor_node, visited_fset_after_move)
if grundy_of_cat_after_move == target_grundy_for_cat_after_move:
print(f"{cat_id_1_indexed} {neighbor_node}")
return
# According to Sprague-Grundy theorem, if nim_sum != 0, a winning move must exist.
# If code reaches here, it implies an issue (e.g. a cat had no valid first moves but N > 1,
# or a logical error in applying the theorem). For this problem structure, a move should always be found.
solve()
qwewe