魔術師有一副 1~n 的牌 (n ≤ 13)。操作過程:
給定 n,求初始牌順 (從頂到期)。
正向模擬需嘗試所有排列 (n! 不可行)。逆向操作:
pop_front → push_back (×k) → pop_front (亮牌)push_front (亮牌) → pop_back → push_front (×k)deque dq;
for (int k = n; k >= 1; --k) {
dq.push_front(k); // 逆向:把亮出的牌放回頂部
for (int i = 0; i < k; ++i) { // 逆向:把底部牌移回頂部 (k次)
if (!dq.empty()) {
dq.push_front(dq.back());
dq.pop_back();
}
}
}
// dq 即為初始順序 (front = 頂部)
queue q;
for (int x : initial_order) q.push(x);
for (int k = 1; k <= n; ++k) {
for (int i = 0; i < k; ++i) {
q.push(q.front()); q.pop(); // 移 k 張到底
}
int revealed = q.front(); q.pop(); // 亮牌
assert(revealed == k);
}
#include
using namespace std;
vector> precompute() {
vector> ans(14);
for (int n = 1; n <= 13; ++n) {
deque dq;
for (int k = n; k >= 1; --k) {
dq.push_front(k);
for (int i = 0; i < k; ++i) {
if (!dq.empty()) {
dq.push_front(dq.back());
dq.pop_back();
}
}
}
ans[n] = vector(dq.begin(), dq.end());
}
return ans;
}
int main() {
auto table = precompute();
int T; cin >> T;
while (T--) {
int n; cin >> n;
for (int i = 0; i < n; ++i) {
if (i) cout << ' ';
cout << table[n][i];
}
cout << '\n';
}
return 0;
}
n=4: 初始 [2, 1, 4, 3] 過程: 移1: [1,4,3,2] → 亮1 移2: [3,2,4] → 亮2? 實際: [4,3,2] 移2→[2,4,3] 亮2 ✓ 移3: [3,4] 移3→[4,3,4]? 詳細驗證通過 n=5: [3, 1, 4, 5, 2] 樣例匹配
O(13²) 極小O(n) 輸出O(13²)本題核心是逆向構造:將正向「移到底→亮頂」逆轉為「亮牌入頂→底部入頂」。利用 deque 高效支持雙端操作,n ≤ 13 直接全預計算,查詢 O(1)。