给出 n 个数,以及数 x ,将这 n 个数变成递增的序列,如果 x 想要于其中的任何一个数 a[i] 交换,那么满足条件 a[i]>x ,问最小交换次数是多少
题目数据范围小,可以暴力模拟,但在这里并没有模拟,但复杂度还是 O(n*n)
将 x 与 a[i] 交换后,a[i] 之前全都是比 x 要小的数,i 之后没有比 x 大的数,且前面的数必须要单调递增,否则没法操作
由于 a[i]>x ,那么经历多次交换之后,那么数组 a 中有一个比 x 大的数被换成 x
而且每次交换都可以将 a[i] 放到最终位置上,既然满足这个条件,那么就可以将有序序列与原来的序列 a 进行比较
如果 i 位置处的数变小了,那么说明被操作了一次,如果 i 位置处变大了,抱歉,没有这种操作
const int N=5e5+5;
int i,j,k;
int n,m;
int a[N];
int main()
{
//IOS;
rush(){
sdd(n,m);
bool ok=1;
vector<int> v;
int cnt,ans;
for(int i=1;i<=n;i++){
sd(a[i]);
if(a[i]>=a[i-1]) continue;
ok=0;
}
if(ok==1) puts("0");
else{
ans=inf;
for(int i=1;i<=n;i++){
v.clear();
v.pb(m);
for(int j=1;j<=n;j++){
if(i==j && a[j]>m) continue;
v.pb(a[j]);
}
if(v.size()>n) continue;
sort(v.begin(),v.end());
cnt=0;
for(int j=1;j<=n;j++){
if(a[j]>v[j-1]) cnt++;
else if(a[j]<v[j-1]){ cnt=inf; break; }
}
ans=min(ans,cnt);
}
if(ans!=inf) printf("%d\n",ans);
else puts("-1");
}
}
PAUSE;
return 0;
}