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.发布与逸出定义 发布对象 : 使一个对象能够被当前范围之外的代码所使用 ...
随机推荐
- jquery的版本 纵多 , 各个版本的插件的融合 ,
有些插件在哪些版本下没有 插件之间因为版本冲突 是得不偿失的事情
- 【WPF学习】第二十八章 程序集资源
WPF应用程序中的程序集资源与其他.NET应用程序中的程序集资源在本质上是相同的.基本概念是为项目添加文件,从而Visual studio可将其嵌入到编译过的应用程序的EXE或DLL文件中.WPF程序 ...
- 每天一道Java题[9]
题目 native关键字的作用是什么? 解答 首先,需了解JNI(Java Native Interface),它是连接Java平台与本地C代码的一个API. 其次,用native关键字声明的方法,是 ...
- JDK源码之StringBuffer与StringBuilder类分析
一 概述 StringBuffer类被 final 所修饰,不能被继承,StringBuffer继承了AbstractStringBuilder类, 是一个可变的字符序列,并且类中方法都有synchr ...
- 保存网页内容到excel
from selenium import webdriverfrom time import sleepfrom selenium.common.exceptions import NoSuchEle ...
- idea|properties文件乱码
案例 在idea 打开有些配置文件,如config.properties,里面中文注释出现乱码 解决方案 点击FILE->Settings->Editor->File Encodin ...
- ProxySQL 基础篇
1.ProxySQL 介绍 ProxySQL 是基于 MySQL 的一款开源的中间件的产品,是一个灵活的 MySQL 代理层,可以实现读写分离,支持 Query 路由功能,支持动态指定某个 SQL 进 ...
- DLL/EXE查看工具Dumpbin
一般情况下,我们需要查看一个DLL或EXE中的包含的函数或是依赖的函数之类的信息,可以使用VS自带的工具dumpbin: 可以直接在命令行下输入dumpbin就可以查看他的使用说明,如果未显示,可以先 ...
- web通信类几个相关知识
1.什么是同源策略及限制? 同源策略限制从一个源加载的文档或者脚本如何与来自另一个源的资源进行交互. 这是一个用于隔离潜在恶意文件的关键安全机制. 所谓同源,就是指两个页面具有相同的协议,主机(也常说 ...
- BZOJ 1046 [HAOI2007]上升序列(LIS + 贪心)
题意: m次询问,问下标最小字典序的长度为x的LIS是什么 n<=10000, m<=1000 思路: 先nlogn求出f[i]为以a[i]开头的LIS长度 然后贪心即可,复杂度nm 我们 ...