news 2026/5/23 1:43:18

【ACWing】153. 双栈排序

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【ACWing】153. 双栈排序

题目地址:

https://www.acwing.com/problem/content/description/155/

Tom最近在研究一个有趣的排序问题。通过2 22个栈S1和S2,Tom希望借助以下4 44种操作实现将输入序列升序排序。

  1. 操作a:如果输入序列不为空,将第一个元素压入栈 S1
  2. 操作b:如果栈S1不为空,将S1栈顶元素弹出至输出序列
  3. 操作c:如果输入序列不为空,将第一个元素压入栈S2
  4. 操作d:如果栈S2不为空,将S2栈顶元素弹出至输出序列

如果一个1 ∼ n 1∼n1n的排列P PP可以通过一系列操作使得输出序列为1 , 2 , … , ( n − 1 ) , n 1,2,…,(n−1),n1,2,,(n1),n,Tom就称P PP是一个”可双栈排序排列”。例如( 1 , 3 , 2 , 4 ) (1,3,2,4)(1,3,2,4)就是一个”可双栈排序序列”,而( 2 , 3 , 4 , 1 ) (2,3,4,1)(2,3,4,1)不是。下图描述了一个将( 1 , 3 , 2 , 4 ) (1,3,2,4)(1,3,2,4)排序的操作序列:<a, c, c, b, a, d, d, b>

当然,这样的操作序列有可能有几个,对于上例( 1 , 3 , 2 , 4 ) (1,3,2,4)(1,3,2,4)<a, c, c, b, a, d, d, b>是另外一个可行的操作序列。Tom希望知道其中字典序最小的操作序列是什么。

输入格式:
第一行是一个整数n nn
第二行有n nn个用空格隔开的正整数,构成一个1 ∼ n 1∼n1n的排列。

输出格式:
输出共一行,如果输入的排列不是”可双栈排序排列”,输出数字0 00
否则输出字典序最小的操作序列,每两个操作之间用空格隔开,行尾没有空格。

数据范围:
1 ≤ n ≤ 1000 1≤n≤10001n1000

如果某个1 ∼ n 1\sim n1n的序列q qq是一个栈序列,那么栈的操作可以如下进行:遍历序列,先将元素q [ i ] q[i]q[i]入栈,每次入栈完检查一下q [ i + 1 : ] q[i+1:]q[i+1:]是不是都比q [ i ] q[i]q[i]大,如果是,则pop。

关于栈序列,有一个定理:
一个序列是栈序列,当且仅当对于任意i < j i<ji<j,不存在k > j k>jk>j使得q [ k ] < q [ i ] < q [ j ] q[k]<q[i]<q[j]q[k]<q[i]<q[j]

证明:
必要性:如果存在i < j < k i<j<ki<j<k使得q [ k ] < q [ i ] < q [ j ] q[k]<q[i]<q[j]q[k]<q[i]<q[j],由于i , j i,ji,j之后都存在一个更小的q [ k ] q[k]q[k],说明遍历到k kk之前,i , j i,ji,j都不能出栈,但是栈底到栈顶必须时刻都是单调下降的,这就矛盾了。
充分性:我们可以证明上面的模拟是可以进行的。假设某个时刻,我们要入栈q [ j ] q[j]q[j],如果此时栈空,当然可以进行;如果栈不空,我们可以证明栈内的元素都大于q [ j ] q[j]q[j],如果不然,找到最大的i < j i<ji<j使得q [ i ] < q [ j ] q[i]<q[j]q[i]<q[j],由于不存在k > j , q [ k ] < q [ i ] k>j,q[k]<q[i]k>j,q[k]<q[i],按照操作q [ i ] q[i]q[i]应该已经出栈了,就矛盾了。所以每次入栈的时候,入栈的元素一定小于栈内所有元素,而判断出栈的时刻可以用上面说的方式,从而整个过程可以顺利进行。

根据这个性质,由于两个栈相对独立,各自操作,所以我们可以将这个序列分为两部分,如果两个点不能在同一个栈中,我们就连一条边,如此做成一个无向图,如果这个图不是二分图,说明不存在划分方式,直接输出0 00,否则说明存在划分。我们用染色的方式,通过S1操作的元素染色为0 00,其余染色为1 11

接下来求操作序列。由于要求字典序最小,我们按照能a就a,能b就b,以此类推的方式来操作。假设遇到了x = a [ j ] x=a[j]x=a[j],同时维护一个变量,记录下一个要pop的数y yy

  1. x xx颜色为0 00,并且要么栈1为空,要么栈1的顶大于x xx,则x xx可以入栈1,执行a;
  2. 当栈1的顶等于y yy,执行b;
  3. x xx颜色为1 11,并且要么栈2空,要么栈2的顶大于x xx,则x xx可以入栈2,执行c;
  4. 当栈2的顶等于y yy,执行d。

代码如下:

#include<algorithm>#include<cstring>#include<iostream>#include<stack>usingnamespacestd;constintN=1010;intn;inta[N],f[N];intcol[N];boolg[N][N];booldfs(intu,intc){col[u]=c;for(inti=1;i<=n;i++)if(g[u][i]){if(c==col[i])returnfalse;if(!~col[i]&&!dfs(i,!c))returnfalse;}returntrue;}intmain(){memset(g,0,sizeofg);scanf("%d",&n);for(inti=1;i<=n;i++)scanf("%d",&a[i]);f[n+1]=n+1;for(inti=n;i;i--)f[i]=min(a[i],f[i+1]);for(inti=1;i<=n;i++)for(intj=i+1;j<=n;j++)if(a[i]<a[j]&&f[j+1]<a[i])g[i][j]=g[j][i]=true;memset(col,-1,sizeofcol);boolflag=true;for(inti=1;i<=n;i++)if(!~col[i]&&!dfs(i,0)){flag=false;break;}if(!flag){puts("0");return0;}string res;stack<int>stk1,stk2;intcur=1;intj=1;for(inti=1;i<=2*n;i++){if(j<=n&&!col[j]&&(stk1.empty()||stk1.top()>a[j])){stk1.push(a[j]);j++;printf("a ");}elseif(stk1.size()&&stk1.top()==cur){stk1.pop();printf("b ");cur++;}elseif(j<=n&&col[j]&&(stk2.empty()||stk2.top()>a[j])){stk2.push(a[j]);j++;printf("c ");}elseif(stk2.size()&&stk2.top()==cur){stk2.pop();printf("d ");cur++;}}}

时间复杂度O ( n 2 ) O(n^2)O(n2),空间O ( n ) O(n)O(n)

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/21 4:49:53

大数据架构自动化运维:从部署到扩缩容

大数据架构自动化运维&#xff1a;从部署到扩缩容关键词&#xff1a;大数据运维、自动化部署、弹性扩缩容、监控告警、AIOps摘要&#xff1a;本文从“开一家永远不打烊的智能餐厅”的生活场景切入&#xff0c;用通俗易懂的语言讲解大数据架构自动化运维的核心逻辑。我们将一步一…

作者头像 李华
网站建设 2026/5/16 13:17:02

位运算求解八皇后问题:极致优雅的性能优化之道

八皇后问题是计算机科学中的经典回溯算法案例&#xff0c;但在大规模棋盘时性能瓶颈明显。今天我们来介绍一种高效优雅的位运算解法&#xff0c;它不仅能大幅提升性能&#xff0c;还能让代码更加简洁清晰。一、位运算基础&#xff1a;八皇后必备的位操作技巧在深入八皇后问题之…

作者头像 李华
网站建设 2026/5/18 23:59:32

34、Shell编程中的流程控制与位置参数使用

Shell编程中的流程控制与位置参数使用 1. 流程控制之case语句 在编程里,流程控制是非常重要的一部分。之前在处理用户选择时,我们会用一系列 if 命令来判断用户选了哪个选项。不过,这种结构在程序里经常出现,所以很多编程语言(像shell)都提供了用于多选择决策的流程控…

作者头像 李华
网站建设 2026/5/21 1:22:28

揭秘边缘端Agent数据持久化难题:4步实现低功耗高可靠存储

第一章&#xff1a;边缘端Agent数据持久化的挑战与意义在物联网和边缘计算快速发展的背景下&#xff0c;边缘端Agent作为连接终端设备与云端服务的核心组件&#xff0c;承担着数据采集、本地处理与状态同步等关键任务。由于边缘设备常面临网络不稳定、资源受限和突发断电等问题…

作者头像 李华
网站建设 2026/5/22 1:48:04

从采集到洞察:工业互联网Agent数据分析的7个必知步骤

第一章&#xff1a;工业互联网Agent数据分析的核心价值在工业互联网体系中&#xff0c;Agent作为部署于边缘设备或关键节点的智能代理程序&#xff0c;承担着数据采集、实时处理与本地决策的重要职责。其产生的数据不仅涵盖设备运行状态、环境参数和操作日志&#xff0c;还包含…

作者头像 李华