火车车厢重排问题

26 篇文章 0 订阅

问题描述:一列货运火车从出发站出发时火车上一共有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;
	}
}

Java火车车厢重排问题是一个经典的数据结构问题,也被称为“火车进站问题”或“车厢重排问题”。该问题的目标是将一列随机顺序的火车车厢按照编号从大到小的顺序重新排列,并且在重排过程中需要使用缓冲铁轨。这个问题可以使用面向对象的方式来解决。 解决这个问题的一种常见方法是使用栈和递归。具体来说,我们可以将每个车厢看作一个对象,并将它们存储在一个栈中。然后,我们可以使用递归来模拟车厢的进出顺序,直到所有车厢都被排列好为止。在递归的过程中,我们需要考虑当前车厢是否可以直接进入目标铁轨,或者是否需要先将其他车厢移动到缓冲铁轨上。 以下是一个简单的Java代码示例,用于解决火车车厢重排问题: ``` import java.util.Stack; public class TrainSorting { private Stack<Integer> station; private Stack<Integer> buffer; private Stack<Integer> output; public TrainSorting() { station = new Stack<Integer>(); buffer = new Stack<Integer>(); output = new Stack<Integer>(); } public void sort(int[] train) { for (int i = train.length - 1; i >= 0; i--) { station.push(train[i]); } sortHelper(train.length); } private void sortHelper(int n) { if (n == 0) { while (!buffer.empty()) { output.push(buffer.pop()); } return; } buffer.push(station.pop()); while (!buffer.empty() && (output.empty() || buffer.peek() < output.peek())) { station.push(buffer.pop()); } sortHelper(n - 1); } public void printResult() { while (!output.empty()) { System.out.print(output.pop() + " "); } } } ``` 在这个示例中,我们首先将所有车厢按照随机顺序压入站台栈中。然后,我们使用sortHelper()方法来递归地将车厢从站台栈移动到输出栈中。在递归的过程中,我们使用缓冲栈来存储当前不能直接移动到输出栈的车厢。最后,我们使用printResult()方法来输出排列好的车厢序列。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值