问题节选自<<数据结构、算法与应用(C++语言描述)>>, 思路与代码为原创, 如有疏漏及问题欢迎指正

问题描述:

一辆列车有n节车厢, 车厢排列乱序(如: 284657139), 但整体车厢序号连续(序号整体没有断), 每节车厢要停靠不同的站台.

现有n个车站从1到n编号, 列车按照从1到n的顺序经过车站, 列车要在车厢号和车站号相同时, 将车厢卸下, 为了便于卸载, 需

要将车厢重新顺序排列. 重排后列车只需每次卸下最后一节车厢即可, 为了方便重排, 现有入轨道, 出轨道以及三个缓冲轨道,

规定列车从入轨道入, 可将当前入轨车厢转入缓冲轨道或直接移至出轨道, 缓冲轨道中的车厢可按从后至前的顺序移至出轨

道, 列车出轨道后即完成重排.

抽象:

即现有一顺序混乱的栈结构, 要将栈内元素重排, 有三个缓冲栈和一个重排后的结果栈

思路:

第一步: 用一变量记录当前结果栈需要的元素值, 之后初始栈元素顺序出栈, 出栈同时判断是否是结果栈所需要的元素, 是则直接

加入结果栈并将当前记录值减一, 否则将元素推入缓冲栈.

第二步: 元素入缓冲栈时对三个缓冲栈从左至右进行检查, 若栈为空, 直接将元素入栈, 否则判断当前栈的栈顶元素值是否小于当

前元素, 是则推入栈中, 否则跳至下一缓冲栈进行检查.

第三步: 对当前三个缓冲栈进行检查, 若当前三个缓冲栈中任意一栈的栈顶元素满足结果栈需求, 将该元素加入结果栈并将记录值

减一, 重复当前步骤, 直至缓冲栈栈顶元素均不满足要求.

重复以上三步即可完成重排

代码如下:

 #include <iostream>
#include <stack>
#include <vector> #define BUFFER_COUNT 2
#define BUFFER_START 0 static int train_number = ; //当前重排列车需求 std::vector<std::stack<int>> vec_buffer_stack; //缓冲轨道
std::stack<int> train; //初始列车
std::stack<int> rearrange_train; //重排列车 void train_init()
{
train.push();
train.push();
train.push();
train.push();
train.push();
train.push();
train.push();
train.push();
train.push();
} void check_train()
{
if (train.empty())
{
return;
} //当前出栈元素符合重排需求,加入重排列车
if (train.top() == train_number)
{
std::cout << "from current train, rearrange train input " << train.top() << std::endl; rearrange_train.push(train.top());
train.pop();
--train_number;
}
} void check_buffer()
{
for (size_t i = BUFFER_START; i <= BUFFER_COUNT; ++i)
{
if (!vec_buffer_stack[i].empty())
{
//缓冲轨道中车厢符合重排需求,车厢加入重排列车
if (vec_buffer_stack[i].top() == train_number)
{
std::cout << "from buffer " << i << ", rearrange train input " << vec_buffer_stack[i].top() << std::endl; rearrange_train.push(vec_buffer_stack[i].top());
vec_buffer_stack[i].pop();
--train_number; //继续检查缓冲轨道
check_buffer();
break;
}
}
}
} void push_train()
{
if (train.empty())
{
return;
}
for (size_t i = BUFFER_START; i <= BUFFER_COUNT; ++i)
{
//缓冲轨道为空,直接将车厢加入
if (vec_buffer_stack[i].empty())
{
std::cout << "buffer " << i << " push " << train.top() << std::endl; vec_buffer_stack[i].push(train.top());
train.pop(); break;
}
//车厢序号大于缓冲轨道尾车厢序号,加入当前车厢
else if (train.top() > vec_buffer_stack[i].top())
{
std::cout << "buffer " << i << " push " << train.top() << std::endl; vec_buffer_stack[i].push(train.top());
train.pop(); break;
}
}
} void rearrange_curr_train()
{
//检查当前结果栈需求车厢号
while (train_number != )
{
//车厢出栈检查
check_train(); //车厢加入缓存
push_train(); //缓存检查
check_buffer();
} }

测试

C++ 解决列车重排问题的更多相关文章

  1. BFS解决九宫重排问题

    问题 1426: [蓝桥杯][历届试题]九宫重排 时间限制: 1Sec 内存限制: 128MB 提交: 215 解决: 47 题目描述 如下面第一个图的九宫格中,放着  1~8  的数字卡片,还有一个 ...

  2. 手淘架构组最新实践 | iOS基于静态库插桩的⼆进制重排启动优化 抖音研发实践:基于二进制文件重排的解决方案 APP启动速度提升超15% 编译期插桩

    抖音研发实践:基于二进制文件重排的解决方案 APP启动速度提升超15% 原创 Leo 字节跳动技术团队 2019-08-09 https://mp.weixin.qq.com/s/Drmmx5JtjG ...

  3. C++11的原子量与内存序浅析

    一.多线程下共享变量的问题 在多线程编程中经常需要在不同线程之间共享一些变量,然而对于共享变量操作却经常造成一些莫名奇妙的错误,除非老老实实加锁对访问保护,否则经常出现一些(看起来)匪夷所思的情况.比 ...

  4. Java 内存模型 ,一篇就够了!

    Java 虚拟机   我们都知道 Java 语言的可以跨平台的,这其中的核心是因为存在 Java 虚拟机这个玩意.虚拟机,顾名思义就是虚拟的机器,这不是真实存在的硬件,但是却可以和不同的底层平台进行交 ...

  5. The All-in-One Note

    基础 操作系统 I/O 模型 阻塞式 I/O 模型(blocking I/O) 描述:在阻塞式 I/O 模型中,应用程序在从调用 recvfrom 开始到它返回有数据报准备好这段时间是阻塞的,recv ...

  6. Java Volatile关键字(转)

    出处:  Java Volatile关键字 Java的volatile关键字用于标记一个变量“应当存储在主存”.更确切地说,每次读取volatile变量,都应该从主存读取,而不是从CPU缓存读取.每次 ...

  7. Java锁机制深入理解

    Java锁机制 背景知识 指令流水线 ​ CPU的基本工作是执行存储的指令序列,即程序.程序的执行过程实际上是不断地取出指令.分析指令.执行指令的过程. ​ 几乎所有的冯•诺伊曼型计算机的CPU,其工 ...

  8. Java 内存模型都不会,就敢在简历上写熟悉并发编程吗

    从 PC 内存架构到 Java 内存模型 你知道 Java 内存模型 JMM 吗?那你知道它的三大特性吗? Java 是如何解决指令重排问题的? 既然CPU有缓存一致性协议(MESI),为什么 JMM ...

  9. Java并发编程 (五) 线程安全性

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.安全发布对象-发布与逸出 1.发布与逸出定义 发布对象 : 使一个对象能够被当前范围之外的代码所使用 ...

随机推荐

  1. Frameworks.Entity.Core 5 EntityValidation

    Project.Core\Frameworks.Entity.Core\EntityValidation\ EntityValidation 1  数值验证DigitAttribute.cs Digi ...

  2. 智能指针shared_ptr使用学习

    当需要shared_ptr实现向上向下转换时,可以使用 dynamic_pointer_cast 来进行转换 下面是例子: #include <memory> using namespac ...

  3. ios---cocoapods 安装与使用 (AFNetworking为例)

    cocoapods 安装与使用 一.CocoaPods是什么? CocoaPods是一个用Ruby写的.负责管理iOS项目中第三方开源库的工具,CocoaPods能让我们集中的.统一管理第三方开源库, ...

  4. java实现字符串翻转

    public class StringReverse { /*一共写了三个函数func1 func2 func3 * 时间: 2019年9月12日9:00 * func1用的反向输出到一个新的字符串中 ...

  5. x01.auto_input: 自动输入

    单位经常要把 excel 表的数据录入系统中,能够自动录入该多好. 花了几天时间,学习了一下 pandas 操作 excel 数据,利用 pyautogui 完成了一个自动录入的小测试,希望对有此需求 ...

  6. Linux 常用工具openssh之scp

    前言 scp命令用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速度.当你服务器硬盘变为只读read  ...

  7. Hello,world!一切的开始

    普及知识 当我们准备开发Java程序时,我们需要两样基础的工具--JDK与IDE.在这里需要解释一下什么是JDK还有IDE.JDK的全称是Java Development kit,即Java开发工具集 ...

  8. 死磕java(2)

    java数据类型 boolean --true--false byte --8位 short --16位 int --32位 long --64位 char float --32位 double -- ...

  9. data structure test

    1.设计算法,对带头结点的单链表实现就地逆置.并给出单链表的存储结构(数据类型)的定义. #include <iostream> #include <cstdlib> #inc ...

  10. Simscape Multibody 教程 —— 入门学习

    写在前面 本文要点: Simscape Multibody 简介 Simscape Multibody 入门学习的推荐学习材料和学习顺序 建模仿真过程中的重要知识 模型的参数设置(Model Work ...