結果
問題 |
No.1153 ねこちゃんゲーム
|
ユーザー |
![]() |
提出日時 | 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()