C++ 解决列车重排问题
问题节选自<<数据结构、算法与应用(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++ 解决列车重排问题的更多相关文章
- BFS解决九宫重排问题
问题 1426: [蓝桥杯][历届试题]九宫重排 时间限制: 1Sec 内存限制: 128MB 提交: 215 解决: 47 题目描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个 ...
- 手淘架构组最新实践 | iOS基于静态库插桩的⼆进制重排启动优化 抖音研发实践:基于二进制文件重排的解决方案 APP启动速度提升超15% 编译期插桩
抖音研发实践:基于二进制文件重排的解决方案 APP启动速度提升超15% 原创 Leo 字节跳动技术团队 2019-08-09 https://mp.weixin.qq.com/s/Drmmx5JtjG ...
- C++11的原子量与内存序浅析
一.多线程下共享变量的问题 在多线程编程中经常需要在不同线程之间共享一些变量,然而对于共享变量操作却经常造成一些莫名奇妙的错误,除非老老实实加锁对访问保护,否则经常出现一些(看起来)匪夷所思的情况.比 ...
- Java 内存模型 ,一篇就够了!
Java 虚拟机 我们都知道 Java 语言的可以跨平台的,这其中的核心是因为存在 Java 虚拟机这个玩意.虚拟机,顾名思义就是虚拟的机器,这不是真实存在的硬件,但是却可以和不同的底层平台进行交 ...
- The All-in-One Note
基础 操作系统 I/O 模型 阻塞式 I/O 模型(blocking I/O) 描述:在阻塞式 I/O 模型中,应用程序在从调用 recvfrom 开始到它返回有数据报准备好这段时间是阻塞的,recv ...
- Java Volatile关键字(转)
出处: Java Volatile关键字 Java的volatile关键字用于标记一个变量“应当存储在主存”.更确切地说,每次读取volatile变量,都应该从主存读取,而不是从CPU缓存读取.每次 ...
- Java锁机制深入理解
Java锁机制 背景知识 指令流水线 CPU的基本工作是执行存储的指令序列,即程序.程序的执行过程实际上是不断地取出指令.分析指令.执行指令的过程. 几乎所有的冯•诺伊曼型计算机的CPU,其工 ...
- Java 内存模型都不会,就敢在简历上写熟悉并发编程吗
从 PC 内存架构到 Java 内存模型 你知道 Java 内存模型 JMM 吗?那你知道它的三大特性吗? Java 是如何解决指令重排问题的? 既然CPU有缓存一致性协议(MESI),为什么 JMM ...
- Java并发编程 (五) 线程安全性
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.安全发布对象-发布与逸出 1.发布与逸出定义 发布对象 : 使一个对象能够被当前范围之外的代码所使用 ...
随机推荐
- 使用doxygen
Getting started with Doxygen 可执行文件doxygen是解析源文件并生成文档的主程序. 另外, 也可以使用可执行文件doxywizard, 是用于编辑配置文件, 以及在图形 ...
- robotframework,移动端(小程序)自动化,解决无法输入中文
1.如何输入中文 方法: 在open application参数最后,新增unicodeKeyboard=True resetKeyboard=True:不加入这两个参数时,中文无法输入
- laravel5.5的服务容器分析
简介 服务容器是Laravel的核心.见名知意,服务容器就是一个存放服务的地方,当我们需要某个服务的时候,我们就可以从这个容器中取出我们需要的服务.用更专业一点的术语来说,官网定义服务容器是这样的: ...
- 多线程之CountDownLatch的用法及原理笔记
前言-CountDownLatch是什么? CountDownLatch是具有synchronized机制的一个工具,目的是让一个或者多个线程等待,直到其他线程的一系列操作完成. CountDownL ...
- 1、通过CP数据文件的方式恢复MySQL 从库 启动后报错:Last_IO_Errno: 1236:A slave with the same server_uuid/server_id as this slave has connected to the master;
1.问题: MySQL从库中查看主从状态: show slave status\G,发现出现IO的报错: Last_IO_Errno: Last_IO_Error: Got fatal error f ...
- Flutter开发之Widget学习
一.Text 组件 属性 textAlign: TextAlign.left, -----文本对齐方式 maxLines: 1, ...
- 场景7:带有Linux网桥的提供商网络
此场景描述了使用带有Linux网桥的ML2插件的OpenStack网络服务的供应商网络实现. 供应商网络通常以灵活性为代价提供简单性.性能和可靠性.与其他场景不同,只有管理员可以管理提供者网络,因为它 ...
- HDU_1494_dp
http://acm.hdu.edu.cn/showproblem.php?pid=1494 能量用0-14表示,dp[i][j]表示走到第i段,所剩能量j的最小时间. #include<ios ...
- HDU4192 Guess the Numbers(表达式计算、栈)
题意: 给你一个带括号.加减.乘的表达式,和n个数$(n\leq 5)$,问你带入这几个数可不可能等于n 思路: 先处理表达式:先将中缀式转化为逆波兰表达式 转换过程需要用到栈,具体过程如下:1)如果 ...
- Codeforces 924 A Tritonic Iridescence(暴力集合交集、相等)
题目链接:点击打开链接 There is a rectangular grid of n rows of m initially-white cells each. Arkady performed ...