火车车厢重排
一列货车共有n节车厢,每个车厢都有自己的编号,编号范围从1~n。给定任意次序的车厢,通过转轨站将车厢编号按顺序重新排成1~n。转轨站共有k个缓冲轨,缓冲轨位于入轨和出轨之间。开始时,车厢从入轨进入缓冲轨,经过缓冲轨的重排进入出轨。缓冲轨按照先进先出方式----队列,编写一个算法,将任意次序的车厢进行重排,.重排后车厢次序为n~1 。 重排成功:则输出,否则,程序终止.
提示:
一列火车的每个车厢按顺序从入轨进入不同缓冲轨,缓冲轨重排后的进入出轨,重新编排成一列货车。
比如:
有 n=9 , 入轨次序为:3 , 6 , 9 , 2 , 4 , 7 , 1 , 5 , 8 。缓冲轨 k = 2。 要将这n节车厢重排成 9,8,7,6,5,4,3,2,1. 假如:任意一节车厢 T ,不能直接从入轨直接移至出轨,那么就必须进入缓冲轨:要求每个缓冲轨都是有序的,及先进入缓冲轨的车厢号小于后入缓冲轨的车厢号。
如图:
图1 图2
图3 图4
代码实现:
#include <iostream>
#include <stdlib.h>
using namespace std;
const int QueueSize = 20;
template <class T>///----------------队列
class CriQueue{
public:
CriQueue(){
front = rear = 0;
};
~CriQueue(){
};
void EnQueue(T x);
T DeQueue();
T GetQueue();
T Get_End_Queue();
void RearrangementTrian(int n , int m);
bool Empty(){///-----------队空?
return front == rear? true : false;
};
bool Full(){///-----------队满?
return (rear+1)%QueueSize == front ? true : false;
};
private:
T data[QueueSize];
int front, rear;
};
template<class T>
void CriQueue<T>::EnQueue(T x)///--------入队
{
if(!Full()){
rear = (rear+1)%QueueSize;
data[rear] = x;
}
}
template<class T>
T CriQueue<T>::DeQueue()///-------------出队
{
if(!Empty()){
front = (front+1)%QueueSize;
return data[front];
}
}
template<class T>
T CriQueue<T>::GetQueue()///---------获得队头元素
{
if(!Empty()){
int i = (front+1)%QueueSize;
return data[i];
}
return 0;
}
template<class T>
T CriQueue<T>::Get_End_Queue()///---------访问队尾元素(为了方便:自己增加的权限)
{
if(!Empty()){
return data[rear];
}
return 0;
}
///------------------------核心思想-----------------------
template<class T>
void CriQueue<T>::RearrangementTrian(int n , int m)///-------火车车厢重排
{
int arr[n]; ///---出轨元素集
int nowOut = 1; ///----车厢编号
int i , j , temp =0 ;
CriQueue<int> Trian[m]; ///---数组队列
while( !Empty() )
{
if(GetQueue() == nowOut){///--------是否可以直接出轨
arr[nowOut++] = DeQueue();
}
else{
for(i = 0 ; i < m ; i++){///-------------判断缓冲轨是否可以出轨
if( Trian[i].GetQueue() == nowOut){
arr[nowOut++] = Trian[i].DeQueue();
i = -1;
}
if(GetQueue() == nowOut){///--------入轨是否可以直接出轨
arr[nowOut++] = DeQueue();
i = -1;
}
}
int max = -1, max_j = -1;
for(j = 0 ; j < m ; j++){///------------选择缓冲轨
if(GetQueue() != nowOut && Trian[j].Get_End_Queue() < GetQueue()){
if(max < Trian[j].Get_End_Queue()){
max = Trian[j].Get_End_Queue();
max_j = j;
}
}
}
if(max == -1 && j == m && nowOut < n){///------ERROR
cout<<"---NO! ( NUM== "<<GetQueue()<<" ) IS--ERROR!----"<<endl;///------m条缓冲轨都不能入,exit(-1),重排失败
exit(-1);
}
else if(max != -1 && j == m && nowOut < n){///-----入缓冲轨队
Trian[max_j].EnQueue(DeQueue());
}
}
}
while(nowOut <= n){ ///----------按顺序出轨
temp = temp%m;
if(Trian[temp].GetQueue() == arr[nowOut-1]+1){
arr[nowOut++] = Trian[temp].DeQueue();
}
temp++;
}
for(temp = n; temp >= 1 ; temp--)///----打印
cout<<arr[temp]<<" ";
}
int main()///----------main()
{
int n , num , m;
bool flag = true;
while( flag ){
CriQueue<int> a;
cout<<"请输入 n m >0"<<endl;///------------ n 车厢 , m 条缓冲轨
cin>>n>>m;
if( n == 0 && m == 0){
flag = false;
break;
}
for( int i = 1 ; i <= n; i++){
cin>>num;
a.EnQueue(num);
}
a.RearrangementTrian(n,m);
cout<<endl<<"---------end-----------"<<endl<<endl;
}
return 0;
}
运行如下:
OK!!!!!!!!