• 【每日一题】补档 CF1792C. Min Max Sort | 思维 | 简单


    题目内容

    原题链接

    给定一个长度为 n n n 的排列 p p p ,每次可以选择 ( x , y ) , x < y (x,y), x(x,y),x<y 两个数,将 x x x 挪到排列最前面, y y y 挪到排列最后面。问至少要操作多少次可以使得这个排列单调递增。

    数据范围

    • 1 ≤ n ≤ 2 ⋅ 1 0 5 1\leq n\leq 2\cdot 10^5 1n2105
    • 1 ≤ p i ≤ n 1\leq p_i\leq n 1pin p i p_i pi 各不相同

    题解

    考虑要使得单调递增,每次必然选择的是 ( x , n − x + 1 ) (x,n-x+1) (x,nx+1)
    但是选择了 ( x , n − x + 1 ) (x,n-x+1) (x,nx+1) ,那么 ( 1 , n ) , ( 2 , n − 1 ) , . . . , ( x − 1 , n − x + 2 ) (1,n),(2,n-1),...,(x-1,n-x+2) (1,n),(2,n1),...,(x1,nx+2) 必然需要都进行一次。

    那么什么时候需要去操作呢?

    我们考虑选择 ( x , n − x + 1 ) (x,n-x+1) (x,nx+1) 时,已经可以在排列中找到一个子序列 ( x + 1 , x + 2 , ⋯   , n − x + 1 , n − x ) (x+1,x+2,\cdots,n-x+1,n-x) (x+1,x+2,,nx+1,nx)

    如果 i n d e x [ x ] > i n d e x [ x + 1 ] index[x]>index[x+1] index[x]>index[x+1] 或者 i n d e x [ n − x + 1 ] < i n d e x [ n − x ] index[n-x+1]index[nx+1]<index[nx] 或者 i n d e x [ x ] > i n d e x [ n − x + 1 ] index[x]>index[n-x+1] index[x]>index[nx+1] ,则我们必须操作 ( x , n − x + 1 ) (x,n-x+1) (x,nx+1) ,否则在当前的排列中就已经找到 ( x , x + 1 , x + 2 , ⋯   , n − x + 2 , n − x + 1 , n − x ) (x,x+1,x+2,\cdots,n-x+2,n-x+1,n-x) (x,x+1,x+2,,nx+2,nx+1,nx) 这个子序列了,那么就不需要操作了。

    此外,操作了 ( x , n − x + 1 ) (x,n-x+1) (x,nx+1) 后, x x x 在最前面, n − x + 1 n-x+1 nx+1 在最后面,那么需要按照 ( x − 1 , n − x + 2 ) , ( x − 2 , n − x + 3 ) , ⋯   , ( 1 , n ) (x-1,n-x+2),(x-2,n-x+3),\cdots,(1,n) (x1,nx+2),(x2,nx+3),,(1,n) 这样的顺序来操作这 x − 1 x-1 x1 对,故有 x x x 次操作。

    时间复杂度: O ( n ) O(n) O(n)

    代码

    #include 
    using namespace std;
    
    void solve() {
        int n;
        cin >> n;
        vector<int> a(n);
        vector<int> pos(n);
        for (int i = 0; i < n; ++i) {
            cin >> a[i];
            pos[a[i] - 1] = i;
        }
    
        int ans = 0;
        int minv = -1, maxv = -1;
        for (int r = n / 2; r < n; ++r) {
            int l = n - 1 - r;
            if (pos[l] > pos[r]) {
                ans = l + 1;
                break;
            }
            if (minv != -1 && (pos[l] > minv || pos[r] < maxv)) {
                ans = l + 1;
                break;
            }
            minv = pos[l];
            maxv = pos[r];
        }
    
        cout << ans << "\n";
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
    
        int T;
        cin >> T;
        while (T--) solve();
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
  • 相关阅读:
    趣学算法 —— 兔子数列
    抖音播映量破500的原因找到了,不是内容不好,而是这5个功能
    基于【GO】的cmf_password加密密码的逻辑,和校验密码逻辑
    生产制造企业仓库管理不到位?ERP系统帮你解决
    Vue脚手架的初次了解/使用
    银行业务头条体系推广
    NX二次开发-UFUN CSYS坐标系转换UF_CSYS_map_point
    Vue3 – Composition Api
    RedisObject各属性结构的作用
    JWT登录认证(2认证)
  • 原文地址:https://blog.csdn.net/weixin_43900869/article/details/134078668