火车车厢重排问题

问题描述:一列货运火车从出发站出发时火车上一共有n节车厢,编号分别是1到n。运货的各节车厢是在入轨上时是随机的顺序,火车头在出轨处,现在要将各节车厢按编号从大到小挂到车头上,其中在入轨与出轨之间有k条缓冲铁轨,将通过缓冲铁轨完成本次的火车车厢的重排。

具体规则:

一、车厢从入轨的前部(即右端)只可以移动到一个缓冲铁轨的顶端或出轨的右端。

二、缓冲铁轨的顶端的车厢只可以移动到出轨的最左端

三、车厢不能从一个缓冲铁轨移动到另一个缓冲铁轨或者再移动到入轨

四、车厢移动到出轨的最左端(即火车头端)后不能再移动

解决步骤:

一、     从入轨端开始移除最右边的车厢如果该车厢正好可以挂在出轨端则直接移到入轨端,然后再在缓冲铁轨中查找是否有接到出轨上的车厢如有则移出如无则开始步骤四;否则先在每条缓冲铁轨中查找。

二、     如果能找到一条缓冲铁轨顶端的车厢编号正好比它大而且和它最接近则移动到该条缓冲铁轨上

三、     如果每一条有车厢的缓冲铁轨的顶端车厢编号都比它小,则再查找有没有空的缓冲铁轨如果有则移动到缓冲铁轨上,否则返回false。

四、     继续开始从入轨端移除最右端的车厢并且开始重复步骤一。

应用的数据结构:

由于对于每一个缓冲铁轨来说都是LIFO后进先出的特点所以可以考虑采用栈的数据结构。

具体实现代码及结果如下:

#include<iostream>
#include<vector>
#include<stack>
#include<deque>
#include<iterator>
#include<algorithm>
using namespace std;

//辅函数:更新缓冲铁轨上的min_buf、min_tra
void updata(vector<stack<int>> & tracks_buf,int & min_buf,int & min_tra)
{
	for (int i = 0;i<tracks_buf.size();i++)
	{
		if(!tracks_buf[i].empty() && min_buf>tracks_buf[i].top())
		{
			min_buf = tracks_buf[i].top();
			min_tra = i;
		}
	}
}
//辅函数:将车厢移到缓冲铁轨上
bool trans(int n,int d,vector<stack<int>> & tracks_buf,int & min_buf,int & min_tra)
{
	//先查找最优缓冲铁轨
	int min_gap = n+1;//d与个缓冲铁轨顶端上大于的车厢与d之间的最小间隔
	int prefer_track = -1;//最优铁轨
	for (int i = 0;i<tracks_buf.size();i++)
	{
		if (!tracks_buf[i].empty() && tracks_buf[i].top()>d && (tracks_buf[i].top()-d)<min_gap)
		{
			min_gap = tracks_buf[i].top()-d;
			prefer_track = i;
		}
	}
	if(-1!=prefer_track)//找到最优缓冲铁轨
	{
		tracks_buf[prefer_track].push(d);
		updata(tracks_buf,min_buf,min_tra);
		return true;
	}
	else
	{
		//再查找是否存在空铁轨
		for (int i = 0;i<tracks_buf.size();i++)
		{
			if(tracks_buf[i].empty())
			{
				tracks_buf[i].push(d);
				updata(tracks_buf,min_buf,min_tra);
				return true;
			}
		}
		//否则返回false;
		return false;
	}
}

/*  火车车厢重排问题
*	datas:火车车厢在入轨上时的序列
*   n : 火车车厢的总节数
*	k :缓冲铁轨的条数
*/
//主要函数
bool fun(vector<int> &datas,deque<int> & results,int n,int k)
{
	int min_buf = n+1;//缓冲铁轨上最小的车厢号
	int min_tra = 0;//最小的车厢所在的缓冲铁轨编号
	vector<stack<int>> tracks_buf(k);//缓冲铁轨数组

	int need = 1;//出轨处需要挂上的车厢号
	while (!datas.empty())
	{
		int d = datas.back();
		datas.pop_back();
		if (d==need)//符合要求直接移到出轨
		{
			results.push_front(need);
			need++;
			//再到缓冲铁轨中查找是否有下一个符合的车厢
			while(min_buf == need)//找到
			{
				results.push_front(need);
				need++;
				//移除缓冲铁轨
				tracks_buf[min_tra].pop();
				//更新min_buf、min_tra
				min_buf = n+2;
				min_tra = 0;
				updata(tracks_buf,min_buf,min_tra);
			}
		}
		else//不符合要求移到缓冲铁轨上
		{
			if(!trans(n,d,tracks_buf,min_buf,min_tra))
			{
				return false;
			}
		}
	}
		return true;
}
int main()
{
	int array[] = {5,8,1,7,4,2,9,6,3};
	deque<int> results;
	vector<int> vec(array,array+sizeof(array)/sizeof(array[0]));
	int n = vec.size();
	int k = 3;//3条缓冲铁轨

	if (fun(vec,results,n,k))
	{
		cout<<k<<"条缓冲铁轨可以将按照";
		copy(vec.begin(),vec.end(),ostream_iterator<int>(cout));
		cout<<"此序列的"<<n<<"节车厢重新排好挂到火车头上。"<<endl;
		cout<<"排好后的序列是:"<<endl;
		copy(results.begin(),results.end(),ostream_iterator<int>(cout));
		cout<<endl;
	}
	else
	{
		cout<<"重排失败!"<<endl;
	}
}

火车车厢重排问题,布布扣,bubuko.com

时间: 2024-08-03 08:53:39

火车车厢重排问题的相关文章

火车车厢重排调度

1 /*************************************************************** 2 *程序名称:火车车厢重排调度 3 *作 者:tbz 4 *完成日期:2014年10月18日 5 ***************************************************************/ 6 #include <queue> 7 #include <iostream> 8 #include "Tra

火车车厢重排问题--队列模拟

①问题描述 一列货运列车共有n节车厢,每节车厢将停放在不同的车站.假定n个车站的编号分别为1-n,即货运列车按照第n站至第1站的次序经过这些车站.为了便于从列车上卸掉相应的车厢,车厢的编号应与车站的编号相同,这样,在每个车站只要卸掉最后一节车厢.所以,给定任意次序的车厢,必须重新排列它们. 车厢的重排工作可以通过转轨站完成.在转轨站中有一个入轨.一个出轨和k个缓冲轨,缓冲轨位于入轨和出轨之间.假定缓冲轨按先进先出的方式运作,设计算法解决火车车厢重排问题. ②基本要求 设计存储结构表示n个车厢.k

堆栈应用(三):火车车厢重排

1.问题描述 一列货运列车共有 n节车厢,每节车厢将停放在不同的车站.假定 n个车站的编号分别为1 ~n,货运列车按照第 n站至第 1 站的次序经过这些车站.车厢的编号与它们的目的地相同.为了便于从列车上卸掉相应的车厢,必须重新排列车厢,使各车厢从前至后按编号 1 到n的次序排列.当所有的车厢都按照这种次序排列时,在每个车站只需卸掉最后一节车厢即可. 为了重排车厢,需从前至后依次检查入轨上的所有车厢.如果正在检查的车厢就是下一个满足排列要求的车厢,可以直接把它放到出轨上去.如果不是,则把它移动到

栈例题-火车车厢重组

一组火车车厢编号1-n 从右向左经过车站 每节车厢可以临时进站(栈),放过主线上的几节车厢后再重新上路跟上. 输入车厢数和希望得到的车厢顺序,判断是否可能. CCF教材下册P149,例6.9 代码如下: 1 #include <iostream> 2 #include <string> 3 #include <cmath> 4 #include <algorithm> 5 using namespace std; 6 struct Stack 7 { 8 i

用JS描述的数据结构及算法表示——栈和队列(基础版)

前言:找了上课时数据结构的教程来看,但是用的语言是c++,所以具体实现在网上搜大神的博客来看,我看到的大神们的博客都写得特别好,不止讲了最基本的思想和算法实现,更多的是侧重于实例运用,一边看一边在心里隐隐歌颂大神的厉害,然后别人的厉害不是我的,所以到底看得各种受打击+头昏脑涨,写这个系列是希望自己能够总结学到东一块.西一下的知识,因为水平有限+经验不足,所以在此只说最基础的思想,附上我自己的算法实现(肯定还有更优解),如果要想看进阶版的,可以在园里搜“数据结构”,各种语言实现和进阶提升的文章有很

C#实现堆栈

堆栈(Stack)是一种特殊的线性表,是一种操作只允许在尾端进行插入或删除等操作的线性表.表尾允许进行插入删除操作,称为栈顶(Top),另一端是固定的,称为栈底(Bottom).栈的操作使按照先进后出或后进先出的原则进行的. 用一片连续的存储空间来存储栈中的数据元素,称为顺序栈(Sequence Stack).类似于顺序表,用一维数组来存放栈中的数据元素.缺点:浪费存储空间. 用链式存储结构来存储的栈为链栈(Linked Stack).链栈通常用单链表来表示. Stack using Syste

绿皮火车的印象以及消失

绿皮火车消失 '绿皮车俱乐部','绿皮车旅行社','绿皮车客栈' ,'绿皮车乡村美食'......坐在K字大头的火车车厢里,咣当咣当的.我的脑海里一下子冒出这些个泡泡来. 早已被淘汰的'绿皮车'今日在哪里?做什么用了?一个现成的企划,一个投资很小的全国连锁,一个容易引起两代人回忆的火车以及与火车相关的故事的全民记忆. 绿车皮是一个标记,是一段铁路历史,是串起长达一个多世纪的旅行记录. 今天乘坐一个区间为两个小时的硬座车颇有感触. 与我,是下乡插队的一段生活记忆链.与历史,是文化大革命初期红卫兵进

《高铁风云录》:铁路与火车的历史,精彩程度不逊于集装箱的历史。讲中国的部分成为资料的堆砌,不够精彩。3星

本书全部资料都是二手的.前半部分讲铁路与火车的发明创造改进的历史,以及日本铁路的发展史,精彩程度不亚于<集装箱改变世界>中的集装箱的历史.后半部分讲中国高铁的发展史,感觉变成资料的堆砌.总体评价3星. 以下是书中一些信息的摘抄: 1:铁路发明的意义再怎么夸大都不为过,这是人类诞生以来第一次能够自如地实现陆上大规模长距离旅行,而这一天的到来到现在还不到200年.#219 2:在铁路的催化下,分裂的德意志走向了统一,并与法国展开了欧洲大陆霸权的争夺,进而引发了两次世界大战:#221 3:瓦特与茶壶

LeetCode#905 - 按奇偶排序数组

题目 给定一个非负整数数组 A,返回一个由 A 的所有偶数元素组成的数组,后面跟 A 的所有奇数元素. 你可以返回满足此条件的任何数组作为答案. 输入:[3,1,2,4] 输出:[2,4,3,1] 输出 [4,2,3,1],[2,4,1,3] 和 [4,2,1,3] 也会被接受. 解题思路 根据题目的描述,我们可以看到这道题只有一个要求,那就是将数组中的偶数全部挪到奇数的前面,另外顺序不计. 解法一 我看到这个题的第一反应是可以使用插入排序来解决这个问题,插入排序主要使用两个for循环,一个用来