C. Min Max Sort

Problem - C - Codeforces

题意:

长度为n的排列,可执行一下操作任意次:

排列中选择两个数,小值移动到当前排列的最前面,大值移动到当前排列的最后面

问最少需要多少次可使排列变成有序增排列

思路:

可以发现一个排列最多经过n/2 次操作一定可以有序.假设经过k次操作排列变成有序,第一次操作一定是选择(k,n-k+1),最后一次选择(1,n),且排列中 k~n-k+1(开区间)一定是有序的。所以我们可以从k的最大值开始,不断减小。当条件不满足时说明这就是最小操作步数.....不知道怎么表达,不太清晰...

#include<bits/stdc++.h>
#define int long long
#define pdd pair<double,double>
#define pii pair<int,int>
// #define x first
// #define y second
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;

const int N=2e5+10;
const int inf=0x3f3f3f3f;

int n;
int a[N];
int pos[N];

void solve(){
    cin >> n;
    for(int i=1;i<=n;i++){
        cin >> a[i];
        pos[a[i]]=i;
    }
    
    int l=(n+1)/2,r=(n+2)/2;
    
    while(l>0  && ((pos[l]<pos[l+1] && pos[r]>pos[r-1]) || l==r ) ){
        l--;
        r++;
    }
    cout << (n-r+l+1)/2 << endl;
}


signed main(){
    ios;
    int t=1;
    cin >> t;

    while(t--){
        solve();
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值