news 2026/1/15 11:13:34

【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/1/14 4:40:28

【Leetcode】1786. Number of Restricted Paths From First to Last Node

题目地址&#xff1a; https://leetcode.com/problems/number-of-restricted-paths-from-first-to-last-node/description/ 给定一个nnn个点mmm条边的无向非负权图&#xff0c;顶点编号为1∼n1\sim n1∼n&#xff0c;每个点到nnn可以求出最短距离&#xff0c;记为d[u]d[u]d[u…

作者头像 李华
网站建设 2026/1/15 7:37:29

【康复效率提升300%的秘密】:深度解析医疗Agent自主调参机制

第一章&#xff1a;医疗康复Agent方案调整的演进与挑战随着人工智能在医疗领域的深度渗透&#xff0c;面向康复治疗的智能Agent系统正经历从规则驱动到数据驱动的范式转变。早期系统依赖预设临床路径和固定决策树&#xff0c;难以应对患者个体差异与动态恢复进程。现代康复Agen…

作者头像 李华
网站建设 2026/1/13 14:58:31

htop入门指南:5分钟掌握Linux系统监控

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 制作一个交互式htop学习应用&#xff1a;1.分章节介绍htop界面元素 2.内置模拟环境供新手练习 3.实时反馈操作正确性。要求采用终端ASCII动画教学&#xff0c;包含成就系统激励学习…

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

传统热部署VS快马AI:效率提升300%的对比实验

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个对比实验项目&#xff0c;要求&#xff1a;1. 左侧传统方式&#xff1a;手动配置Spring Boot DevTools的完整流程 2. 右侧AI方式&#xff1a;通过自然语言描述生成配置 3. …

作者头像 李华