NOIP 双栈排序(贪心算法)

题目描述

Tom最近在研究一个有趣的排序问题。如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序。
在这里插入图片描述
操作a
如果输入序列不为空,将第一个元素压入栈S1
操作b
如果栈S1不为空,将S1栈顶元素弹出至输出序列
操作c
如果输入序列不为空,将第一个元素压入栈S2
操作d
如果栈S2不为空,将S2栈顶元素弹出至输出序列

如果一个1~n的排列P可以通过一系列操作使得输出序列为1,2,…,(n-1),n,Tom就称P是一个“可双栈排序排列”。例如(1,3,2,4)就是一个“可双栈排序序列”,而(2,3,4,1)不是。下图描述了一个将(1,3,2,4)排序的操作序列:<a,c,c,b,a,d,d,b>
在这里插入图片描述

当然,这样的操作序列有可能有几个,对于上例(1,3,2,4),<a,c,c,b,a,d,d,b>是另外一个可行的操作序列。Tom希望知道其中字典序最小的操作序列是什么。
【输入】
输入文件twostack.in的第一行是一个整数n。
第二行有n个用空格隔开的正整数,构成一个1~n的排列。
【输出】
输出文件twostack.out共一行,如果输入的排列不是“可双栈排序排列”,输出数字0;否则输出字典序最小的操作序列,每两个操作之间用空格隔开,行尾没有空格。

【输入输出样例1】
输入:
4
1 3 2 4
输出:
a b a a b b a b

思路

能弹出,则弹出,优先放在S1中(输出的方案按照字典序输出,所以优先放在S1中)
首先思考:
能放在S1中的情况:
1.S1栈顶为0,即S1没有数
2.当前输入值小于S1栈顶,而且S2栈顶没有数
肯定不能放在S1的情况:
1. 当前输入的值大于S1栈顶
特殊情况:当前输入值小于S1、S2栈顶
例如:
S1栈顶 = 10,S2栈顶= 8,现在进来一个7,看上去很难判断7到底放在哪里,如果放S1,后面来个9,再来个6,就无法放了。但是如果先来的是6,并且已经排完了1-5,那么我们可以在后续操作中把7弄走仔细想想不难发现,7不能放在S1中,当且仅当存在一个位置K,满足a[k]>7,且在k之后有位置L,满足a[L]<7也就是说(i, j, k)不能同时在栈中,当且仅当(i < j < k)且(a[k] < a[i] < a[j])
在这里插入图片描述

程序流程

在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1001;
int N, a[MAXN], s1[MAXN], tp1, s2[MAXN], tp2; //a存放的是输入序列 
vector<char
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值