給定一個基數為 p 的乘法表,但數字 0..p-1 被一個排列重新映射,且行列順序被打亂。輸入給出打亂後的表:每行 p 個方程 `i*j=xy`(xy 為兩位數,高位 x 低位 y)。要求還原排列:輸出 0..p-1 分別映射為哪個數字。解唯一。p ≤ 500。
// 讀入 p 和打亂表 a[i][2*j], a[i][2*j+1] 表示 i行 j列的結果兩位
// 找 0 的行:所有結果相同的行
for i in 0..p-1:
for j in 1..2p-1:
if a[i][j] != a[i][j-1] break
if j == 2p: ans[0] = i; break
// 統計每行高位去重數
for i in 0..p-1:
cnt = 0; clear vis
for j in 0..2p-1 step 2:
if not vis[a[i][j]]: vis[a[i][j]] = 1; cnt++
if cnt == 1 and i != ans[0]: ans[1] = i // 映射為1的行:高位只有0
else if cnt != 1: ans[cnt] = i // 映射為 cnt-1 的行
// 輸出 ans[0..p-1]
Input: 4 2 3 1 1 3 2 1 0 1 1 1 1 1 1 1 1 3 2 1 1 3 1 1 2 1 0 1 1 1 2 1 3 1 0 1 1 1 2 1 3 0 Output: Case #1: 1 3 2 0
解讀:原 0→1, 1→3, 2→2, 3→0。
利用乘法表 0 行恆定、非零行高位多樣性隨映射值增長的數學特性,O(p^2) 掃描還原排列。關鍵在於識別高位去重計數與映射值的線性關係。