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.发布与逸出定义 发布对象 : 使一个对象能够被当前范围之外的代码所使用 ...
随机推荐
- Django2.0 配置 media
1.setting.py文件 MEDIA_URL='/media/' MEDIA_ROOT=os.path.join(BASE_DIR,"media") 注意:MEDIA_ROOT ...
- 关于Hive中case when不准使用子查询的解决方法
在公司用Hive实现个规则的时候,遇到了要查询某个字段是否在另一张表中,大概情况就是 A表: id value1 value2 1 100 0 2 101 1 3 102 1 B表: value1 1 ...
- Qt Installer Framework翻译(4)
教程:创建安装程序 本教程描述如何为一个小项目创建一个简单的安装程序: 本节描述创建安装程序所必须完成的步骤: 创建一个包文件夹,其中将包含所有配置文件和可安装的包. 创建一个配置文件,其中包含有关如 ...
- ASP.NET Core下Ocelot的简单使用
一.创建demo项目 1.新建webapi项目,命名为“DemoProject”,去掉HTTPS勾选 using Microsoft.AspNetCore.Mvc; using System.Coll ...
- devops与CICD
前言 devops的概念已经在前一章已经说过了,下面介绍CICD的概念. CI(Continuous Integration,持续集成) 持续集成中,开发人员将会频繁地向主干提交代码,这些新提交的代码 ...
- Spring 核心功能演示
Spring 核心功能演示 Spring Framework 简称 Spring,是 Java 开发中最常用的框架,地位仅次于 Java API,就连近几年比较流行的微服务框架 SpringBoot, ...
- CCNA的基础知识及要点
一.CCNA中的基础知识及要点: 2.网线的制作:568B:橙白,橙,绿白,蓝,蓝白,绿,棕白,棕 568A的排线顺序从左到右依次为:白绿.绿.白橙.蓝.白蓝.橙.白棕.棕.实验目的:初学者常为做网线 ...
- Docker 容器数据 持久化(系统学习Docker05)
写在前面 本来是可以将数据存储在 容器内部 的.但是存在容器内部,一旦容器被删除掉或者容器毁坏(我亲身经历的痛,当时我们的大数据平台就是运行在docker容器内,有次停电后,不管怎样容器都起不来.以前 ...
- 使用纯C++迭代器编写归并排序
第一次尝试用C++迭代器编写算法,使用的是纯迭代器 void mergeSort(vector<int>::iterator beg, vector<int>::iterato ...
- CCF_ 201312-2_ISBN号码
水. #include<cstdio>#include<string>#include<iostream>using namespace std; int main ...