結果
問題 |
No.3047 Verification of Sorting Network
|
ユーザー |
|
提出日時 | 2025-03-06 02:08:12 |
言語 | PyPy3 (7.3.15) |
結果 |
WA
|
実行時間 | - |
コード長 | 4,678 bytes |
コンパイル時間 | 439 ms |
コンパイル使用メモリ | 82,456 KB |
実行使用メモリ | 88,628 KB |
最終ジャッジ日時 | 2025-03-06 02:08:21 |
合計ジャッジ時間 | 6,984 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | WA * 3 |
other | WA * 61 |
ソースコード
#!/usr/bin/env python3 import sys input_data = sys.stdin.read().strip().split() if not input_data: sys.exit(0) it = iter(input_data) T = int(next(it)) out_lines = [] # 各比較器が交換を起こしたかを記録するフラグ(全テストケース共通で更新) # テストケース毎に個別に初期化する for _ in range(T): N = int(next(it)) M = int(next(it)) # 読み込み:比較器 j の入力番号 A_j(1-indexed) A = [int(next(it)) for _ in range(M)] B = [int(next(it)) for _ in range(M)] # 今回のテストケース内で,各比較器 j (0-indexed)が少なくとも1度交換を起こしたか swapped = [False]*M # 各候補入力(「逆順入力」:左側に a 個の1,右側に N-a 個の0, # すなわち,入力列は 1^a 0^(N-a);ただし a=0, N は sorted となるので候補は a=1..N-1) # 各候補についてシミュレーションし,最終状態を記録する. # ここでは,入力・出力は 0‐1列を整数として表現する. # ただし,入力は「自然な順番」 # すなわち,X[0]~X[N-1](左から右)とし,sorted の状態は 0^(N-a) につづく 1^(a) となる. final_state = dict() # key: a (1<= a <= N-1), value: 最終状態(整数) # 各候補についてシミュレーション for a in range(1, N): # candidate: 左側 a 個が 1,右側 N-a 個が 0 # つまり,X[0..a-1] = 1, X[a..N-1] = 0. # 状態は整数 state で表し,X[i] は state の中で,左から i 番目の桁(0-indexed)とする. # 実際には,整数のビット表現では最上位ビットが X[0] に対応するようにする. state = ((1 << a) - 1) << (N - a) # シミュレーション(比較器は順に動作) for j in range(M): # 比較器 j は (A[j], B[j]) で与えられる(1-indexed,かつ A[j] < B[j]) # ここでは X[0]~X[N-1](左から)とし, # 比較器は X[A[j]-1] と X[B[j]-1] を比較し,もし X[A[j]-1] > X[B[j]-1] なら交換 ai = A[j] - 1 bi = B[j] - 1 # 状態 state の左から i 番目の値は,(state >> (N-1-i)) & 1 で得られる bit_a = (state >> (N - 1 - ai)) & 1 bit_b = (state >> (N - 1 - bi)) & 1 if bit_a == 1 and bit_b == 0: # 交換を記録 swapped[j] = True # 交換:X[ai] と X[bi] の値を交換 # state からは,該当するビットをそれぞれ変更する state = state - (1 << (N - 1 - ai)) + (1 << (N - 1 - bi)) final_state[a] = state # sorted state(入力の popcount = a のとき)は, # 左側 (0~N-a-1) が 0,右側 (N-a~N-1) が 1 # 整数で表すと,sorted_state = (1 << a) - 1 (ただし N 桁で考える) is_sorting = True unsorted_pop = [] # ソート失敗候補の a 値(=候補の popcount) for a in range(1, N): target = (1 << a) - 1 # 下 a 桁が1,それ以外は0(N 桁表現) if final_state[a] != target: is_sorting = False unsorted_pop.append(a) if is_sorting: out_lines.append("Yes") # ソーティングネットワークの場合,交換が一度も起こらなかった比較器番号 j (1-indexed) をすべて出力 never_swapped = [str(j+1) for j in range(M) if not swapped[j]] out_lines.append(str(len(never_swapped))) out_lines.append(" ".join(never_swapped)) else: out_lines.append("No") # ネットワークがソートできない場合, # 各失敗候補の最終状態について,出力列 Y において Y[k] > Y[k+1] となり得る位置 k (1<= k <= N-1) を求める inv_set = set() # ※ 各候補は popcount a(a=unsorted_pop の候補) # 最終状態をリストに変換:Y[i] = (state >> (N-1-i)) & 1, i=0..N-1(i=0 が左端) for a in unsorted_pop: s = final_state[a] Y = [ (s >> (N-1-i)) & 1 for i in range(N) ] for i in range(N-1): if Y[i] > Y[i+1]: # 問題文では,k 番目 (1<= k <= N-1) は,出力列の # Y[k] と Y[k+1] の比較(すなわち,i = k-1 と k) inv_set.add(i+1) inv_list = sorted(inv_set) out_lines.append(str(len(inv_list))) out_lines.append(" ".join(str(x) for x in inv_list)) sys.stdout.write("\n".join(out_lines))