描述
描述
某列车调度站的铁道联接结构如Figure 1所示
其中,A为入口,B为出口,S为中转盲端。所有铁道均为单轨单向式:列车行驶的方向只能是从A到S,再从S到B;另外,不允许超车。因为车厢可在S中驻留,所以它们从B端驶出的次序,可能与从A端驶入的次序不同。不过S的容量有限,同时驻留的车厢不得超过m节。
设某列车由编号依次为{1, 2, …, n}的n节车厢组成。调度员希望知道,按照以上交通规则,这些车厢能否以{a1, a2, …, an}的次序,重新排列后从B端驶出。如果可行,应该以怎样的次序操作?
输入
共两行。
第一行为两个整数n,m。
第二行为以空格分隔的n个整数,保证为{1, 2, …, n}的一个排列,表示待判断可行性的驶出序列{a1,a2,…,an}。
输出
若驶出序列可行,则输出操作序列,其中push表示车厢从A进入S,pop表示车厢从S进入B,每个操作占一行。
若不可行,则输出No。
样例
Example 1
Input
5 2
1 2 3 5 4
Output
push
pop
push
pop
push
pop
push
push
pop
pop
Example 2
Input
5 5
3 1 2 4 5
Output
No
限制
1 ≤ n ≤ 1,600,000
0 ≤ m ≤ 1,600,000
时间:2 sec
空间:256 MB
题目分解
这个问题可以分为几步:step1:求入栈序列的全排列 ;step2:根据出栈规则求合法的出栈序列;step3:若S的容量小于A,进行再一步的筛选 step4:输出序列 step5:输出操作
1.全排列
详细描述在这
https://blog.csdn.net/m0_38008539/article/details/95178298
提供两种方法
def perm_byOrder(stack_in,begin,end):
"""
求全排列 -> 调换顺序的方法
:param lis: 需要求全排列的序列
:param begin: 移动变量
:param end: 固定变量
:return: 全排列
"""
if begin >= end: #结束标志
stack_perm.append(copy.copy(stack_in))
# print(stack_in)
else:
i = begin
for num in range(begin,end):
stack_in[num],stack_in[i] = stack_in[i],stack_in[num] #固定当前位置,在进行下一位的排列
perm_byOrder(stack_in,begin+1,end)
# 调用结束之后还需要回溯将交换位置的元素还原,以供其他下降路径使用(二叉树)
stack_in[num],stack_in[i] = stack_in[i],stack_in[num]
def perm_bySlice(stack_in):
"""
全排列 -> 利用切片的方法
:param stack_in: 需要求全排列的序列
:return: 全排列
"""
if len(stack_in) == 1: #结束条件
return [stack_in]
reslut = []
for i in range(len(stack_in)):
s = stack_in[:i] + stack_in[i+1:] #stack_in[i] 不仅如此下一次递归
p = perm_bySlice(s)
for x in p:
reslut.append(stack_in[i:i+1] + x)
return reslut
2.判断合法输出序列
也有两种方法
- 方法1
将入栈队列和出栈队列进行比较,引入辅助堆栈,将入栈数据和出栈队列进行比较,不相等则继续压栈,相等则辅助堆栈弹出,最后若辅助堆栈为空,证明序列合法
class stack():
def __init__(self, length):
self.length = length
self.top = -1
self.stack = []
def noEmpty(self): #判断不为空
if self.top == -1:
return False
else:
return True
def push(self,data):
if self.top >= self.length:
print('堆栈已满\n')
else:
self.top += 1
self.stack.append(data)
def top_value(self):
return self.stack[self.top]
def pop(self):
if self.noEmpty() is False:
print('堆栈是空的')
else:
self.stack.pop(self.top)
# print('弹出的数据为:%d' % (self.stack.pop(self.top)))
self.top -= 1
def judge_stack_byCompare(stack_out):
"""
通过入栈序列和出栈序列的比较
:param stack_out: 要判断的序列
:return: True or False
"""
stack_in