題解:CF454B Little Pony and Sort by Shift

wuzihenb發表於2024-08-20

題目描述

題目傳送門

給定一個長度為 $n$ 的陣列 $a$,每次可以將最後一個元素移動到第一個,問:至少需要幾次操作,讓序列從小到大排好序,若無解輸出 $-1$。


演算法1

(暴力列舉)

不難想到,將最後一個元素拼接在第一個元素之前,就可以實現將鏈轉換成環,再依次遍歷在陣列 $a_i$ 中長度為 $n$ 的子串(可以想象成在陣列 $a$ 中有一個長度為 $n$ 會滑動的視窗),再檢驗是否滿足題目要求就可以了。

時間複雜度 $O(n^3)$

C++ 程式碼

請讀者自行實現


演算法2

經過我不斷摸索(看了一眼題解),發現將最後一個元素移到最前邊,實際上就是為了將滿足 $$a_{i-1} > a_i$$ 的兩個元素分離,成為合法的序列,但是如果有兩組以上這樣的元素,就無法滿足題目要求了。

時間複雜度 $O(n)$


C++ 程式碼

#include <iostream>
using namespace std;

const int N = 100010;
int n;
int a[N];

int main() {
	cin >> n;
	for (int i = 1; i <= n; i++) cin >> a[i];
	
	a[0] = a[n];
	
	int cnt = 0, ans = -1;
	for (int i = 0; i <= n; i++)
		if (a[i-1] > a[i]) { // 統計逆序對
			cnt++;
			ans = n - i + 1;
		}
	ans %= n; // 如果ans > n,肯定也可以用ans % n來滿足題目要求
	cout << (cnt > 1 ? -1 : ans) << endl;
	
	return 0;
}

相關文章