题目链接:https://codeforces.com/contest/1792/problem/C
题意:
输入乱序的1到n的排序数组,有三种操作使其有序:
选择x和y俩个元素将他们从数组中去除。
在x和y中选择小的插入到队头
在x和y中选择大的插入到队尾
理解:对于2,3操作其实都只是让2个数字有序,那么将俩个不合理的数字去掉数组同样也可以变得有序,所以可以都用同一种操作,就是1操作,对于不合理的直接去掉就可以了。
那么最大的操作次数就是n/2,此时数组为0或1.
去除数字应该从中间的去除,如果说中间的数字有不合理的地方,那就没有再排序的必要了,直接去掉,否则就由内到外去遍历看看是否符合顺序。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5;
int a[2*N];
int pos[2*N];
int t,n;
int main()
{
ios::sync_with_stdio(false);
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
pos[a[i]]=i;//确定各个数字应该的位置
}
int ans=(n%2==1);
for(int i=1;i<=n/2;i++){
int l,r;
//由中间到外依次比较顺序
if(n%2==1){
l=(n+1)/2-(ans+1)/2;
r=(n+1)/2+(ans+1)/2;
if(l<1||pos[r]-pos[r-1]<0||pos[l+1]-pos[l]<0) break;
ans+=2;
}
else {
l=n/2-ans/2;
r=n/2+1+ans/2;
if(l<1||pos[r]-pos[r-1]<0||pos[l+1]-pos[l]<0) break;
ans+=2;
}
}
// cout<<ans<<endl;
没被保留的数字就是需要操作的,都按删除2个处理
cout<<(n-ans)/2<<endl;
}
return 0;
}