笔试题(七):火车进出站

# 给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号,火车站只有一个方向进出,
# 同时停靠在火车站的列车中,只有后进站的出站了,先进站的才能出站。
# 要求输出所有火车出站的方案,以字典序排序输出。
# 数据范围:1≤n≤10
# 进阶:时间复杂度:O(n!),空间复杂度:O(n)
# 输入描述:
# 第一行输入一个正整数N(0 < N <= 10),第二行包括N个正整数,范围为1到10。
# 输出描述:
# 输出以字典序从小到大排序的火车出站序列号,每个编号以空格隔开,每个输出序列换行,具体见sample。


# #### 先简介两个递归函数的应用 ####
# 递归函数应用实例1:计算套圆的半径
def func(n):
    if n == 1:
        r = 3
        return r
    return func(n - 1) + 2
# print(func(5))


# 递归函数应用实例1:计算n的阶乘
def factorial(n):
    if n == 1:
        r = 1
        return r
    return n * factorial(n - 1)
# print(factorial(6))
# ##############################


# # 解题思路:使用三个变量,分别表示待进站火车、待出站火车、出站火车。
# # 每次作业(只操作一辆车)有两种情况发生,一种是进站作业,一种是出站作业
# # 将作业结果当作参数递归下去,递归结束标志是待进站火车和待出站火车都没有了
def func1(wait, get_in, out):
    # 方法1:用进、出,等待三个状态列表来完成
    if not wait and not get_in:  # 进站列表为空,待出站列表也为空(说明全部已经出站,直接返回结果即可)
        res.append(" ".join(map(str, out)))
    if wait:  # 如果待出站列表不为空(则安排进出站)
        func1(wait[1:], get_in + [wait[0]], out)
    if get_in:  # 如果进站列表不为空(则安排出站,注意:先进后出!)
        func1(wait, get_in[:-1], out + [get_in[-1]])


def func2(order, in_num, out_num):
    # 方法2:
    if len(order) == N * 2:  # 如果全部进站出站完成,则打印结果
        stack = []
        temp = []
        temp_trains = trains.copy()
        for o in order:
            if o == "i":  # 进站
                stack.append(temp_trains.pop(0))
            else:
                temp.append(str(stack.pop()))  # 先进后出
        res.append(" ".join(temp))
        return res
    if in_num < N:  # 还有车辆没进站(则逐个安排进站)
        func2(order+["i"], in_num+1, out_num)
    if out_num < N and out_num < in_num:  # 还有车辆没出站, 且待进站车辆数小于待出站车辆数(则逐个安排出站)
        func2(order+["o"], in_num, out_num+1)


def func3(cur_idx, in_trains, out_trains):
    # 方法3:
    # 如果原始火车列表的最后一个元素已经进站,此时只能出站,将入站列表中的火车倒序加入出站火车中
    if trains[-1] in in_trains:  # 车辆全部已进站
        res.append(' '.join(out_trains + in_trains[::-1]))
    elif not in_trains:  # 如果进站列表为空,则开始安排进站
        func3(cur_idx + 1, in_trains + [trains[cur_idx]], out_trains)
    else:  # 否则,就既有可能进站也有可能出站
        # 进站,当前待出站火车索引加1,进站列表加上当前火车
        func3(cur_idx + 1, in_trains + [trains[cur_idx]], out_trains)
        # 出站,进站火车列表减去最后一个元素,出站列表加上进站列表刚刚出站的火车
        func3(cur_idx, in_trains[:-1], out_trains + [in_trains[-1]])
        # 递归“遍历”本质:利用def下if条件句特点;如果有两个选项会一直循环至验证所有可能解


if __name__ == "__main__":
    N = 3
    train = "1 2 3"
    trains = list(map(str, train.split()))
    res = []
    func1(trains, [], [])
    print("func1: ", res)

    res = []
    func2(['i'], 1, 0)  # 首次只能进站
    print("func2: ", res)

    res = []
    func3(0, [], [])
    print("func3: ", res)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Trisyp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值