CodeForces 1455 D. Sequence and Swaps
题目大意:
给一个 n n n 个元素数组,和一个整数 x x x,你可以执行 0 0 0 次或者若干次操作。
从数组选择一个元素 a i > x a_i > x ai>x ,交换 a i a_i ai 和 x x x 。
问最小操作几次能使数组有序,没有答案输出 − 1 -1 −1
思路:
有一个重要的结论: x x x 一定会越来越大
假设 a i > x a_i > x ai>x,但是不操作,那么在后面 $a_j > x $ 并且 $ j > i$ ,也不能操作了,因为在这里操作,那么 a j a_j aj 就会等于 x x x,而前面 a i > x a_i > x ai>x ,所以就无法有序。
所以的话,如果选择不操作,那么整个数组后面都不能操作,也就是整个数组已经有序了,否则必须操作。
根据这个思路每次操作完检查数组是否有序即可,复杂度 O ( n 2 ) O(n^2) O(n2)
代码:
#include <bits/stdc++.h>
using namespace std;
#define me(a, b) memset(a, b, sizeof(a))
#define IOS() ios::sync_with_stdio(false), cin.tie(0)
#define endl '\n'
typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
const int INF = 0x3f3f3f3f;
const int maxn = 2e5 + 5;
const ll mod = 1e9 + 7;
int a[maxn];
bool isok(int n)
{
bool flag = true;
for(int i = 1; i < n; ++i)
if(a[i] < a[i-1]) return false;
return true;
}
void solve()
{
int n, x;
cin >> n >> x;
for(int i = 0; i < n; ++i)
cin >> a[i];
if(isok(n)) {
cout << 0 << endl;
return ;
}
int ans = 0;
for(int i = 0; i < n; ++i) {
if(a[i] > x) {
swap(a[i], x);
++ans;
if(isok(n)) {
cout << ans << endl;
return;
}
}
}
cout << -1 << endl;
}
int main()
{
IOS();
int T;
cin >> T;
while(T--) {
solve();
}
return 0;
}
总结:
官方题解可以说做到 O ( n ) O(n) O(n),但我还是想不出