【二分图+栈排序】题解:P1155 [NOIP2008 提高组] 双栈排序_二分图染色_贪心_模拟_C++算法竞赛
文章目录P1155 [NOIP2008 提高组] 双栈排序题解P1155 [NOIP2008 提高组] 双栈排序题目描述Tom 最近在研究一个有趣的排序问题。如图所示通过2 22个栈S 1 S_1S1​和S 2 S_2S2​Tom 希望借助以下4 44种操作实现将输入序列升序排序。操作a \verb!a!a将第一个元素压入栈S 1 S_1S1​。操作b \verb!b!b将S 1 S_1S1​栈顶元素弹出至输出序列。操作c \verb!c!c将第一个元素压入栈S 2 S_2S2​。操作d \verb!d!d将S 2 S_2S2​栈顶元素弹出至输出序列。如果一个1 ∼ n 1\sim n1∼n的排列P PP可以通过一系列合法操作使得输出序列为( 1 , 2 , ⋯ , n − 1 , n ) (1,2,\cdots,n-1,n)(1,2,⋯,n−1,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 \texttt {a,c,c,b,a,d,d,b}a,c,c,b,a,d,d,b。当然这样的操作序列有可能有几个对于上例( 1 , 3 , 2 , 4 ) (1,3,2,4)(1,3,2,4)a,b,a,a,b,b,a,b \texttt{a,b,a,a,b,b,a,b}a,b,a,a,b,b,a,b是另外一个可行的操作序列。Tom 希望知道其中字典序最小的操作序列是什么。输入格式第一行是一个整数n nn。第二行有n nn个用空格隔开的正整数构成一个1 ∼ n 1\sim n1∼n的排列。输出格式共一行如果输入的排列不是“可双栈排序排列”输出0。否则输出字典序最小的操作序列每两个操作之间用空格隔开行尾没有空格。样例 #1样例输入 #14 1 3 2 4样例输出 #1a b a a b b a b样例 #2样例输入 #24 2 3 4 1样例输出 #20样例 #3样例输入 #33 2 3 1样例输出 #3a c a b b d提示30 % 30\%30%的数据满足n ≤ 10 n\le10n≤10。50 % 50\%50%的数据满足n ≤ 50 n\le50n≤50。100 % 100\%100%的数据满足n ≤ 1000 n\le1000n≤1000。2021.06.17 加强 by SSerxhs。hack 数据单独分为一个 subtask 防止混淆。noip2008 提高第四题题解这道题有难度。遇到这种题我们先找规律假设只有一个栈那满足什么条件的序列无法成功排序呢尝试一下1,2,3的所有排列中只有2,3,1不行。1,2,3,4的所有排列中1,3,4,2不行我们只看[2,3,1]和[3,4,2]不难找到一个共性若a[i],a[j],a[k]满足ijk且a[i]a[j],a[i]a[k]则无法完成单栈排序简单证明这样的话会使较大的a[j]压在较小的a[i]上且a[k]无法在a[i]之前出栈。所以一定会造成矛盾的情况。考虑如何判断数字冲突三层循环太费时间可以只枚举(i,j)对于a[k]预处理一个后缀最小值Min。若a[i]Min[j1]则后面一定有一个或若干个不满足条件的a[k]所以这就是需要双栈排序的原因了。那么我们要思考一个问题哪些数字要进入第一个栈哪些数字要进入第二个栈很明显就是冲突了的那些数字只有让那些数字不进入同一个栈才有成功排序的可能。我们很自然地就会想到——二分图染色。对于每一对a[i],a[j]建一条无向边然后对图进行二分图判定染色如果能成功染色则说明有合法的方案反之则不能接下来可以通过用两个栈模拟的方式求出操作步骤。比较难以解释详见代码然后题目的另一个难点出现了要求操作字典序最小压入第一个栈弹出第一个栈压入第二个栈弹出第二个栈我们肯定要对每个处理步骤一顿贪心。我们假设染色时染成0要进入第一个栈染成1要进入第二个栈对于二分图染色判断从小到大枚举所有的点并且在进行染色时以0开始。这样染完色之后序号较小的一定会进入第一个栈减小字典序然后模拟时对于字典序小的操作优先做。即能先做a就先做a再能先做b就先做b这里还有一个坑点假设S1[7,5],S2[8,6]我们要把9放入栈S1中正常第一眼想到的方案是先把所有9的都弹栈再把9放入S1序列bdbda但这是错的最优的方案是当7弹栈后就把9放入栈S1中这样会节省字典序序列bdbad也就是说假设要把x放入栈St那么只要满足 St为空 或 St.top()x此时就直接把x压入栈中这样是最优的模拟还有一些细节见代码#includebits/stdc.husingnamespacestd;constintmaxn1005;intn,a[maxn],Min[maxn];// Min是a的后缀最小值vectorintG[maxn];intcol[maxn];// 二分图染色数组intdfs(intu,intc){col[u]c;for(intv:G[u]){if(col[v]c)return0;if(col[v]-1dfs(v,c^1)0)return0;}return1;}voidsolve(){cinn;for(inti1;in;i)cina[i];// 求后缀最小值Min[n]a[n];// 初始化for(intin-1;i1;i--){Min[i]min(Min[i1],a[i]);}// 判断是否存在三元组(a[i],a[j],a[k])满足ijk且a[i]a[j],a[i]a[k]a[k]可以利用后缀最小值来检查for(inti1;in;i){for(intji1;jn-1;j){if(a[i]a[j]a[i]Min[j1]){// 因为jk所以a[k]要取Min[j1]G[i].push_back(j);// 建边准备跑二分图染色G[j].push_back(i);// 如果两个点有边相连则它们一定不能放在同一个栈中}}}memset(col,-1,sizeofcol);// 初始化染色数组为-1boolflagtrue;// 能否成功二分图染色for(inti1;in;i){// 按照下标从小到大遍历这样序号小的一定先染上0保证字典序最小if(col[i]-1dfs(i,0)0)flagfalse;}// 如果不是二分图的话说明不能成功匹配就可以直接返回了if(!flag){cout0\n;return;}// 然后大模拟 染色结束后染0的点一定入栈1染1的点一定入栈2stackintS[3];// S[1],S[2]表示两个栈intpos1;// pos表示当前该放哪个数for(inti1;inposn;i){// 循环当前要把哪个数入栈if(col[i]0){// 应该放入第一个栈while(posa[i]){// 在while里面要注意按照字典序进行操作即操作序号字典序小的先操作这样保证输出的答案字典序最小if(S[1].empty()||S[1].top()a[i]){// 这样就可以直接把a[i]放入栈并退出循环// 这是节省字典序的方法一定要注意这个细节S[1].push(a[i]);couta ;break;}// 下面的操作是为了弹出pos让a[i]早点入栈elseif(!S[1].empty()S[1].top()pos){// 注意判栈空的情况S[1].pop();coutb ;pos;}elseif(!S[2].empty()S[2].top()pos){S[2].pop();coutd ;pos;}}}else{// 放入栈1同理while(posa[i]){if(!S[1].empty()S[1].top()pos){S[1].pop();coutb ;pos;}elseif(S[2].empty()||S[2].top()a[i]){S[2].push(a[i]);coutc ;break;}elseif(!S[2].empty()S[2].top()pos){S[2].pop();coutd ;pos;}}}}// 最后如果栈中还有剩余的元素就继续弹栈。// 因为此时两个栈里已经排好序从栈顶到栈底所以只要按照大小关系输出即可while(S[1].size()||S[2].size()){if(S[2].empty()){S[1].pop();coutb ;}elseif(S[1].empty()){S[2].pop();coutd ;}elseif(S[1].top()S[2].top()){S[1].pop();coutb ;}elseif(S[1].top()S[2].top()){S[2].pop();coutd ;}}}signedmain(){ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);solve();return0;}

相关新闻

水晶轻奢跨境合规全手册:拆解品牌字体、天鹅剪影、水晶纹理三重商标完整保护边界

水晶轻奢跨境合规全手册:拆解品牌字体、天鹅剪影、水晶纹理三重商标完整保护边界

跨境知识产权|案件编号:26-cv-00179|水晶首饰 / 轻奢配饰 / 家居摆件 / 服饰印花 / POD 定制卖家必读避雷指南奥地利百年水晶巨头 Swarovski AG 施华洛世奇全新批量商标维权落地,SWAROVSKI 标准文字、标志性天鹅图形 Logo、水晶切…

2026/7/23 7:19:28阅读更多 →
用户请求量激增,Kimi暂停C端新用户订阅并拆分新用户权益提升服务稳定性

用户请求量激增,Kimi暂停C端新用户订阅并拆分新用户权益提升服务稳定性

Kimi暂停C端新用户订阅,启动算力扩容昨日晚间,Kimi发布公告表示,因近期用户请求量快速增长,现有算力集群承载压力接近极限,所以决定暂停C端新用户订阅,并启动算力扩容计划。这一举措直接反映出Kimi当前面临…

2026/7/22 21:07:28阅读更多 →
2025最新成功率94%抄底副图+选股指标用于大跌后的反包波段,无未来函数电脑手机均使用

2025最新成功率94%抄底副图+选股指标用于大跌后的反包波段,无未来函数电脑手机均使用

1:出信号最好选形成平底或底部抬高的票!或缩量回调不破前低的票!最好信号当天有长下影线最好 2:或配合选kdj背离发生的票!可结合通达信的ene轨道线,选轨道走平或上翘的票! 3:买入不涨,及时止损!或根据自身情况选择适…

2026/7/22 10:18:11阅读更多 →
医疗影像小目标检测技术解析与YOLOv8优化实践

医疗影像小目标检测技术解析与YOLOv8优化实践

1. 医疗影像小目标检测的技术挑战与解决方案在医疗影像分析领域,小目标检测一直是个棘手的问题。以眼底病变检测为例,我们需要在视网膜图像中识别出微小的出血点、渗出物或微动脉瘤,这些目标往往只占整张图像的几个像素。传统检测方法直接处理…

2026/7/23 10:30:56阅读更多 →
教育Agent的个性化学习实现与挑战

教育Agent的个性化学习实现与挑战

1. 教育Agent的现状与挑战教育Agent这个概念最近在智能教育领域越来越火,但真正能落地的产品却寥寥无几。作为一名在教育科技领域摸爬滚打多年的从业者,我见过太多号称"个性化学习"的系统,最后都变成了简单的题目推荐引擎。问题出在…

2026/7/23 10:30:56阅读更多 →
2024年7月生成式AI关键进展与选型指南

2024年7月生成式AI关键进展与选型指南

1. 2024年7月生成式AI领域关键进展全景 2024年7月无疑是生成式AI发展的关键转折点,四大科技巨头相继发布了具有里程碑意义的新模型。作为从业者,我亲历了这些技术突破带来的行业震动:Mistral与Nvidia联合推出的NeMo 12B重新定义了小模型性能边…

2026/7/23 10:30:56阅读更多 →
河南郑州巡逻巡检机器人采购找江南北机器人 中部枢纽园区智能巡检机器人助力中原数字安防建设

河南郑州巡逻巡检机器人采购找江南北机器人 中部枢纽园区智能巡检机器人助力中原数字安防建设

河南省地处中部枢纽,郑州作为省会城市,联动洛阳、开封、平顶山、安阳、鹤壁、新乡、焦作、濮阳、许昌、漯河、三门峡、南阳、商丘、信阳、周口、驻马店、济源等全域产业带,形成庞大的制造业、物流业、文旅业、能源化工产业集群。随着中部地区…

2026/7/23 10:30:56阅读更多 →
大模型架构优化与神经网络搜索技术详解

大模型架构优化与神经网络搜索技术详解

1. 大模型高级工程师考试练习题解析作为一名参与过大模型相关项目评审的技术专家,我经常遇到工程师们对这类考试题目感到困惑的情况。今天我们就来深入拆解这道练习题,不仅告诉你答案,更要让你理解背后的技术逻辑和实际应用场景。这道题目看似…

2026/7/23 10:30:56阅读更多 →
LabVIEW XY Graph中使用真实时间戳显示多曲线

LabVIEW XY Graph中使用真实时间戳显示多曲线

阅读时间: 6分钟 适用人群: LabVIEW开发工程师、数据记录系统设计者、需要绝对时间对齐的多通道监测系统开发者一、问题背景在某些工业应用场景中,工程师需要使用绝对时间戳(如2024-03-15 14:30:25.123)作为X轴坐标&…

2026/7/23 10:28:56阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/23 0:56:31阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/23 0:56:31阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/23 0:56:31阅读更多 →
Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具 【免费下载链接】chitchatter Secure peer-to-peer chat that is serverless, decentralized, and ephemeral 项目地址: https://gitcode.com/gh_mirrors/ch/chitchatter Chitchatter是一款革命性的安…

2026/7/23 0:00:28阅读更多 →
从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

更多请点击: https://intelliparadigm.com 第一章:从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表) 当AI副业主理人不再仅满足于单次服务交付,而是主动构建可复用、可裂变、可…

2026/7/23 0:00:28阅读更多 →
油泥处理设备哪里能买到

油泥处理设备哪里能买到

油泥处理设备哪里有?这是许多从事油田、炼化、清罐业务的从业者最关心的问题。根据河南三丰环保设备有限公司的行业经验,选购油泥处理设备的核心在于设备能否适配当地环保法规与原料特性,而非单纯看价格。该公司总经理王钦田先生指出&#xf…

2026/7/23 0:00:28阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/22 22:56:18阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/22 18:55:50阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/22 18:55:50阅读更多 →