結果
| 問題 | No.3400 Nana's Plus Permutation Game (7 + 7) ÷ 7 |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-11-25 02:28:35 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
RE
|
| 実行時間 | - |
| コード長 | 5,702 bytes |
| 記録 | |
| コンパイル時間 | 254 ms |
| コンパイル使用メモリ | 82,768 KB |
| 実行使用メモリ | 96,264 KB |
| 平均クエリ数 | 3443.75 |
| 最終ジャッジ日時 | 2025-12-06 23:34:17 |
| 合計ジャッジ時間 | 8,512 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | RE * 3 TLE * 2 -- * 72 |
ソースコード
#ai回答4
import sys
import random
# 再帰深度の制限緩和
sys.setrecursionlimit(20000)
def solve():
# Nの読み込み (ジャッジは各テストケースでNを出力してくる)
try:
line = sys.stdin.readline()
while line and not line.strip(): # 空行飛ばし
line = sys.stdin.readline()
if not line:
return
N = int(line.strip())
except ValueError:
return
# --- ジャッジに合わせた入出力関数 ---
def query(i, j):
# ジャッジの Q[0]==1 に対応: "1 i j"
print(f"1 {i} {j}", flush=True)
try:
res_line = sys.stdin.readline()
if not res_line: return -1
return int(res_line.strip())
except ValueError:
return -1
def answer(p_list):
# ジャッジの Q[0]==2 に対応: "2 p1 p2 ..."
# p_list は 0-indexed なのでそのまま出力用に整形
# ジャッジ側は check_P = Q[1:] で受け取るため、要素だけを並べる
print(f"2 {' '.join(map(str, p_list))}", flush=True)
# -------------------------------------------------------
# アルゴリズム本体
# -------------------------------------------------------
indices = list(range(1, N + 1))
# Phase 1: 最初の有効なペアを見つけ、ピボット p を決定する
p = -1
# ランダムなペアを生成するジェネレータ
def random_pair_generator():
while True:
a, b = random.sample(indices, 2)
yield a, b
pair_gen = random_pair_generator()
tested = set()
# Nが小さいときはすぐ見つかる。最大 N 回程度試行すれば十分。
for _ in range(N + 5):
u, v_node = next(pair_gen)
if u > v_node: u, v_node = v_node, u
if (u, v_node) in tested: continue
tested.add((u, v_node))
res = query(u, v_node)
if res != -1:
# 成功したらその片方をピボットにする
p = u
break
# 万が一見つからなかった場合のフォールバック
if p == -1:
p = indices[0]
# Phase 2: グラフ構築 (p との和を全探索)
adj = {}
in_degree = {i: 0 for i in indices}
for i in indices:
if i == p: continue
res = query(p, i)
if res != -1:
adj[i] = res
in_degree[res] += 1
# ヘッド(入次数0)の抽出 = 値が 1..v であるノード群
heads = [i for i in indices if in_degree[i] == 0]
v = len(heads) # p の値
head_set = set(heads)
# Phase 3: ヘッド内の順序特定 (1, 2, ..., v の特定)
head_val = {}
if v == 1:
head_val[heads[0]] = 1
else:
# Step 3-0: チェーンの長さで 1 の候補を絞る
chain_len = {}
for h in heads:
curr = h
length = 0
while curr in adj:
curr = adj[curr]
length += 1
chain_len[h] = length + 1
max_len = max(chain_len.values())
candidates = [h for h in heads if chain_len[h] == max_len]
one_node = -1
if len(candidates) == 1:
one_node = candidates[0]
else:
# 候補が複数ある場合、総当たりスコア計算
# 自分自身との和も含める (1+1=2 vs 2+2=4)
scores = {h: 0 for h in candidates}
for h1 in candidates:
for h2 in candidates:
res = query(h1, h2)
if res in head_set:
scores[h1] += 1
one_node = max(scores, key=scores.get)
head_val[one_node] = 1
# Step 3-2: 1 を使って 2, 3, ..., v を特定
# 1 + x = x+1
curr = one_node
unknown_heads = set(heads)
unknown_heads.remove(one_node)
for val in range(2, v + 1):
found_next = -1
if len(unknown_heads) == 1:
found_next = list(unknown_heads)[0]
else:
# query(1, curr) -> value(curr)+1 のノード
res = query(one_node, curr)
if res in head_set:
found_next = res
if found_next != -1:
head_val[found_next] = val
curr = found_next
if found_next in unknown_heads:
unknown_heads.remove(found_next)
else:
break
# Phase 4: 全要素の復元
# インデックス 1..N の順列 P を作成
P = [0] * N # 0-indexed for result output
for h in heads:
val_start = head_val[h]
curr = h
current_v = val_start
while True:
# inputのPは1-indexedだが、配列としては P[i-1] に格納するか、
# そのままリストを作る。
# ジャッジは `P_inv[P[i]] = i+1` ... つまり P は [p1, p2, ..., pN]
# ここでは P[curr-1] = current_v とする
P[curr - 1] = current_v
if curr in adj:
curr = adj[curr]
current_v += v
else:
break
# 解答出力
answer(P)
# メインループ
line = sys.stdin.readline()
while line and not line.strip():
line = sys.stdin.readline()
if line:
try:
T_cases = int(line.strip())
for _ in range(T_cases):
solve()
except ValueError:
pass