P7714 「EZEC-10」排列排序

题目出处:

「EZEC-10」排列排序 - 洛谷

题目内容:

小 E 给你一个长度为 nnn 的排列 p1,p2,⋯ ,pn 。小 E 想要把它排序。

小 E 每次可以花区间长度,即 r−l+1 的代价,选择排列中的任意一段区间 [l,r],并将 [l,r] 从小到大排序。

现在你可以让他进行若干次这个操作,直到 p 中元素的值从 1 到 n 按升序排序,即对于 1 到 n 的每一个 i,都有 pi=i 。

小 E 问你,他花的代价最少为多少?

输入格式

本题有多组询问,第一行有一个数 T 表示询问组数。

对于每组询问:

第一行给出一个整数 n。

第二行 n 个整数,由空格隔开,代表排列 p 中元素的值。

输出格式

T 行,每行一个整数表示一组询问的答案。

输入

2
3
1 3 2
4
3 2 1 4

输出

2
3

数据规模与约定

【样例 1 说明】

对于第一组数据,可选择区间 [2,3] 进行排序。

对于第二组数据,可选择区间 [1,3] 进行排序。

数据保证,1 <= T, ∑n <= 10^6。

思路:双指针

双指针,做指针设为l,右指针设为 r,l 从1循环到 n,通过下标是否与值相等确定数是否在正确的位置:正确则 l++ 进入下一循环;否则,判断当前 l 所在的循环里第 l 个数的值是否大于右端 r ,如果大于则扩大右端 r 的范围,通过设的 tem 维护,第 r 个与下一个(第 r+1 )中最大的保留(如果还没找到最大的 tem 的对应位置),使循环让所有 l 到新的 r 都能排好队,且下一个正常,也即该段成功排好序列,得出排好该序列的代价 minr ,minr累加到最后得到总的代价。

AC代码

#include<bits/stdc++.h>
using namespace std;

int num[1000005];
int main()
{
    int t,i,j; cin>>t;
    while(t--)
    {
        int n,l,r,minr=0,tem=0; cin>>n;
        for(i=1;i<=n;i++) cin>>num[i];
        for(l=1;l<=n;)
        {
            if(num[l]==l) l++;
            else 
            {
                tem=num[l];
                r=l+1;
                tem=max(tem,num[r]);
                while(tem>r)
                {
                    r++;
                    tem=max(tem,num[r]);
                }
                minr+=r-l+1;
                l=r+1;
            }
        }
        cout<<minr<<endl;
    }
    return 0;
}

谢谢。😘

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值