• 【NOIP模拟】排序


    题面

    众所周知,熟练掌握至少一种排序算法是参加NOIP的必备技能。常见的排序算法有冒泡排序、归并排序、快速排序、奇偶排序、猴子排序、梳排序、鸡尾酒排序、臭皮匠排序等。  在这里,介绍一种利用栈进行排序的方法。例如,当数组中的元素为 1, 3, 2 时,我们可以利用栈对其进行排序: 1 入栈; 3 入栈; 3 出栈; 2 入栈; 2 出栈; 1 出栈。在这个例子中,出栈序列是 3, 2, 1,因而实现了对数组的排序。  遗憾的是,在不打乱入栈顺序的前提下,有时仅仅借助一个栈是不能实现对数组的完全排序。例如给定数组 2, 1, 3,借助一个栈,能获得的字典序最大的出栈序列是 3, 1, 2。(2 入栈; 1 入栈; 3 入栈; 3 出栈; 1 出栈; 2 出栈)  现请你借助一个栈,在不打乱入栈顺序的情况下,对数组进行从大到小排序。当无法完全排序时,请输出字典序最大的出栈序列。

    分析

    其实也是一眼题,但是不幸死于细节(蠢到成功被样例误导)

    要让字典序最大,就要让相对大的尽量早出来,所以需要处理一个后缀最大

    即在这个数后面的数中,最大的数是多少

    我们需要维护一个栈和未被输出的最大值outmax,如果当前栈顶就是outmax,那么就先输出它,然后用当前栈顶的后缀最大更新outmax

    然后判断当前栈顶是否比outmax要大,如果是,一直输出并弹栈。当时就是这考虑漏了...因为样例是2 1 5 3 4

    最后所有数都入过栈后,输出栈内剩下的数

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define N 1010000
    int n,top,cnt,outmax;
    int a[N],s[N],ans[N],maxs[N];
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        outmax=n;
        for(int i=n;i>=1;i--)
            maxs[i]=max(maxs[i+1],a[i]);
        for(int i=1;i<=n;i++)
        {
            s[++top]=a[i];
            if(a[i]==outmax)
            {
                top--;
                ans[++cnt]=outmax;    
                outmax=maxs[i+1];
                while(s[top]>outmax)
                    ans[++cnt]=s[top],top--;
            }    
        }    
        while(top)
        {ans[++cnt]=s[top];top--;}
        for(int i=1;i<=n;i++)
            printf("%d ",ans[i]);
        return 0;    
    }
    “Make my parents proud,and impress the girl I like.”
  • 相关阅读:
    【docker】命令学习
    docker 安装mysql
    Docker DockerFile案例 自定义的tomcat9
    尚硅谷 Docker DockerFile案例 ONBUILD命令案例
    dockerfile 案例2 CMD ENTRYPOINT命令案例
    Dockerfile案例
    Dockerfile解析
    数据卷容器
    Dockfile添加数据卷
    容器数据卷
  • 原文地址:https://www.cnblogs.com/NSD-email0820/p/9653293.html
Copyright © 2020-2023  润新知