思路:
首先 n n n 必须在最后面,然后才有可能把比它小的数一个一个归位。否则 n n n 本身就不可能满足条件,答案就是-1。
然后看如何归位。显然如果有一对数,大的在前面,小的在后面,那么大的数必须要用一次操作把它放到后面。因为操作一次只会改变一个数的位置,其他数的相对位置是不变的,所以除非两个数原本的相对位置就是合法的,否则必须需要一次操作把大数放到后面。而挤走的大数只需要按顺序进行操作即可,一个数只需要操作一次,挤走一个,答案就加一。
这种后面的小数把前面的大数挤走的情形很像单调栈,所以使用单调栈模拟一下过程,最后看一下有多少个数被挤出去了就是答案。
code:
#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;
int n;
stack<int> s;
int main(){
cin>>n;
for(int i=1,t;i<=n;i++){
cin>>t;
while(!s.empty() && s.top()>t)s.pop();
s.push(t);
}
if(s.top()!=n)cout<<-1;
else cout<<n-s.size();
return 0;
}