結論:

當 \(n\geq 6\) 時,若 \(n\) 是奇數且輸入序列的逆序對數是奇數,則無解,否則有解。

當 \(n=4\) 或 \(n=5\) 時,答案個數及其有限,只有這個環是 \(1\) 到 \(n\) 的排列(順時針或逆時針均可,如 \(2,3,4,1\)、\(2,1,4,3\))時有解,否則無解。但因為題目中 \(n\geq 8\) 所以這種情況你無需考慮。

證明:

\(n<6\) 的特殊情況暴搜即可證明,下面不妨假設 \(n\geq 6\)。

首先我們注意到,我們可以對序列 \(1,2,3,4,5,6\),不交換序列首尾交接處的元素把 \(1,2,3,4,5,6\) 變成 \(6,2,3,5,4,1\) 或 \(6,5,3,4,2,1\) 或 \(6,4,5,3,2,1\)。證明不必多說,暴搜即可。

我們可以證明,當 \(n\) 為奇數時,題中操作不會改變序列逆序對數的奇偶性。證明如下:

題目中的操作等價於只對序列進行兩種操作:

  • 將前四個元素翻轉;
  • 將第一個元素移到末尾。

對於第一種操作,顯然前 \(4\) 個元素之一與後面的元素形成的逆序對數不變,後面元素互相形成的逆序對數也不變,只需考慮前 \(4\) 個元素互相形成的逆序對數。設原來此數為 \(x\),則順序對數為 \(6-x\),翻轉後逆序對數即為 \(6-x\),逆序對數變化量為 \(|x-(6-x)|=2|x-3|\) 為偶數,所以操作 \(1\) 不會改變序列逆序對數的奇偶性。

對於第二種操作,假設原來元素 \(1\) 和其他元素形成的逆序對數為 \(y\),則之後該元素和其他元素形成的逆序對數變為 \(n-1-y\),而 \(n\) 是奇數,所以操作 \(2\) 也不會改變序列逆序對數的奇偶性。

由此可知,若 \(n\) 是奇數且輸入序列的逆序對數是奇數,則無解。

下面我們證明其他情況必有解:

我們可以先把元素 \(1\) 歸位,只要元素 \(1\) 在位置 \(4\),就可以翻轉過來。同理只要元素 \(1\) 出現在位置 \(1,4,3,5,2,6\dots\) 任何位置,都可以把元素 \(1\) 歸位。可以同理歸位元素 \(2\)。然後:

若忽略元素 \(1\)、\(2\) 後有解,則由前面的結論知不忽略是也有解,只要把翻轉序列首尾交接處的操作換掉即可。

即把長度為 \(n\) 序列的問題轉化為了長度為 \(n-2\) 序列的問題,又因為當 \(n\) 為奇數時操作不會改變逆序對數奇偶性,我們只要證明 \(n=6,7\) 時結論成立即可。

暴力搜尋可以驗證結論的確成立。綜上可得本題結論。

程式碼:

當然可以用歸併排序或樹狀陣列求逆序對數,但本題資料規模小所以不需要。

#include <bits/stdc++.h>
using namespace std;
int main()
{
int T, n, a[500];
cin >> T;
while(T--)
{
cin >> n;
for(int i = 0; i < n; ++i)
cin >> a[i];
bool x = true; // 求逆序對數的奇偶性
if(n & 1)
for(int i = 0; i < n; ++i)
for(int j = i+1; j < n; ++j)
if(a[i] > a[j])
x = !x;
puts(x ? "possible" : "impossible");
}
return 0;
}

同步於洛谷部落格