arc110c
arc110c
大意
给定一个 \(N\) 的排列 \(p\) ,
你需要进行 \(N-1\) 次操作,每次操作选定 \(i\) ,交换 \(p_i,p_{i+1}\)
每个 \(i\) 仅能且必须要被选择一次
问:
能否让序列最终升序
存在输出操作顺序
不存在的话输出 \(-1\)
思路
emmm...
如果我们操作了一次 \(k\) ,那么左边就无法再到达右边。
所以我们必须首先将 \(n\) 放回到数组的最后一位。
不妨假设 \(n\) 所在位置的下标为 \(k\) ,那么 \(k-n\) 操作无法再被选定。
所以我们寻找下一个值与下标小于 \(k\) 的数并操作。
最后,如果数组仍旧无序,那么肯定不存在操作顺序
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
#define ll long long
#define ull unsigned long long
#define cint const int&
#define Pi acos(-1)
const int mod = 998244353;
const int inf_int = 0x7fffffff;
const ll inf_ll = 0x7fffffffffffffff;
const double ept = 1e-9;
int n;
int a[2010000];
int to[2000100];
int ans[2000100], cnt;
int main() {
cin >> n;
for(int i=1; i<=n; i++) {
cin >> a[i];
to[a[i]] = i;
}
int mn = n;
for(int i=n; i>=1; i--)
if(to[i] != i && to[i] < mn) {
mn = to[i];
for(int j=to[i]; j<i; j++) {
ans[++cnt] = j;
swap(a[j], a[j+1]);
}
}
if(cnt != n-1) {
cout << -1 << endl;
return 0;
}
for(int i=1; i<=n; i++)
if(a[i] != i) {
cout << -1 << endl;
return 0;
}
for(int i=1; i<=cnt; i++)
cout << ans[i] << endl;
return 0;
}
-8,46min