火车车厢重排


火车车厢重排

 

        一列货车共有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!!!!!!!!

 

 


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值