• 【每日一题】补档 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
  • 相关阅读:
    如何实现将拖动物体限制在某个圆形内--实现方式vue3.0
    课设总结【硬件课设】
    远程连接服务器上搭建jupyter notebook
    HALCON 2D高精密测量项目全流程解析
    关于 Hypervisor的理解
    秋招失足,拿到这份“Java 高分指南(25 专题)”,金三银四翻盘有望
    用googletest写cpp单测
    【操作系统】进程间的通信——信号
    R语言重复测量方差分析的多重比较
    react antd 主题
  • 原文地址:https://blog.csdn.net/weixin_43900869/article/details/134078668