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

①问题描述

一列货运列车共有n节车厢,每节车厢将停放在不同的车站。假定n个车站的编号分别为1~n,即货运列车按照第n站至第1站的次序经过这些车站。为了便于从列车上卸掉相应的车厢,车厢的编号应与车站的编号相同,这样,在每个车站只要卸掉最后一节车厢。所以,给定任意次序的车厢,必须重新排列它们。

车厢的重排工作可以通过转轨站完成。在转轨站中有一个入轨、一个出轨和k个缓冲轨,缓冲轨位于入轨和出轨之间。假定缓冲轨按先进先出的方式运作,设计算法解决火车车厢重排问题。

②基本要求

  • 设计存储结构表示n个车厢、k个缓冲轨以及入轨和出轨;

  • 设计并实现车厢重排算法;

  • 分析算法的时间性能。

③设计思想

假设有3个缓冲轨,入轨中有9节车厢,次序为5,8,1,7,4,2,9,6,3,重排后,9节车厢出轨次序为9,8,7,6,5,4,3,2,1。重排过程如下:

3号车厢不能直接移至出轨(因为1号车厢和2号车厢必须排在3号车厢之前),因此,把3号车厢移至H1。6号车厢可放在H1中3号车厢之后(因为6号车厢将在3号车厢之后出轨)。9号车厢可以继续放在H1中6号车厢之后,而接下来的2号车厢不能放在9号车厢之后(因为2号车厢必须在9号车厢之前出轨)。因此,应把2号车厢移至H2,4号车厢可以放在H2中2号车厢之后,7号车厢可以继续放在4号车厢之后,如图4所示。至此,1号车厢可通过H3直接移至出轨,如图5所示。由于5号车厢此时仍在入轨中,所以把8号车厢移动至H2,这样就可以把5号车厢直接从入轨移至出轨,如图6所示。此后,可依次从缓冲轨中移出6号、7号、8号和9号车厢,如图7所示。

图4
将369、247依次入缓冲轨

图5
将1移至出轨,234移至出轨

图6
将8入缓冲轨,5移至出轨

图7
将6789移至出轨

由上述重排过程可知:在把车厢c移至缓冲轨时,车厢c应移动到这样的缓冲轨中:该缓冲轨中队尾车厢的编号小于c;如果有多个缓冲轨满足这一条件,则选择队尾车厢编号最大的缓冲轨;否则选择一个空的缓冲轨。

⑤思考

  • 如果缓冲轨按后进先出的方式工作,即用栈表示缓冲轨,应如何解决火车车厢重排问题?

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

#include<iostream>

using
namespace std;

class
Queue

{

public:

    struct
Node

    {

        int
data;

        Node * next;

        Node():next(NULL) {}

        Node(int
a):data(a),next(NULL) {}

    };

    Node * Front;

    Node * rear;

    int
length;

    Queue()

    {

        Node * p = new
Node();

        Front = p;

        rear = p;

        length = 0;

    }

    int
inQueue(int
a)

    {

        Node * p = new
Node(a);

        rear -> next = p;

        rear = rear -> next;

        length ++;

    }

    int
showrear()

    {

        return
rear->data;

    }

    int
showfront()

    {

        return
Front->next->data;

    }

    void
outQueue()

    {

        Node * p = Front -> next;

        Front -> next = p -> next;

        delete
p;

        length--;

    }

    void
printf()

    {

        Node * p = Front -> next;

        for(int
i = 0 ; i < length ; i++)

        {

            cout<<p->data<<" ";

            p = p -> next;

        }

    }

    bool
isEmpty()

    {

        return
length == 0;

    }

};

int
main()

{

    int
n , k ;//n代表车厢数,k代表轨道

    int
nowOut = 1;//要输出的车厢编号

    cout<<"input n:"<<endl;

    cout<<"input k:"<<endl;

    cout<<"input train"<<endl;

    cin>>n>>k;

    Queue dusk[k+2];//0到k-1代表缓冲轨道,k代表入轨,k+1代表出轨

    for(int
i = 0 ; i < n ; i++)//输入入队车厢号

    {

        int
a ;

        cin>>a;

        dusk[k].inQueue(a);

    }

    while(!dusk[k].isEmpty())//出轨不为空的时候循环

    {

        int
flag = 0;//判断进入新的缓冲轨还是进入非空缓冲轨道。

        //0进入新的缓冲轨道,非0进入非空缓冲轨道

        int
z = 0;//判断是否能直接出轨。0为不能直接出轨,非0为可出轨。

        int
flag_end = 0;//退出循环判定

        if(dusk[k].showfront()==nowOut)//如果出轨队头车厢号等于现在要出轨的车厢号

        {

            for(int
i = 0 ; i < k ; i++)//遍历所有循环轨,找出一个空的

            {

                if(dusk[i].isEmpty())//找到空的循环轨,输出

                {

                    cout<<dusk[k].showfront()<<" train by trace "<<i+1<<" out."<<endl;

                    dusk[k+1].inQueue(dusk[k].showfront());

                    nowOut++;

                    dusk[k].outQueue();

                    z++;

                    flag++;

                    break;

                }

            }

        }

        if(z==0)//如果不能直接出轨,找到比当前要出轨的车厢小的非空轨道,并入轨

        {

            for(int
i = 0 ; i < k ; i++)

            {

                if(!dusk[i].isEmpty()&&(dusk[i].showrear()<dusk[k].showfront()))

                {

                    cout<<dusk[k].showfront()<<" train in "<<i+1<<" trace."<<endl;

                    dusk[i].inQueue(dusk[k].showfront());

                    dusk[k].outQueue();

                    flag ++;

                    break;

                }

            }

        }

        //如果找不到比当前要出轨的车厢小的非空轨道,就找空的缓冲轨,并入轨

        if(flag == 0)

        {

            for(int
i = 0 ; i < k ; i++)

            {

                if(dusk[i].isEmpty())

                {

                    cout<<dusk[k].showfront()<<" train in "<<i+1<<" trace."<<endl;

                    dusk[i].inQueue(dusk[k].showfront());

                    dusk[k].outQueue();

                    break;

                }

                if(i==k-1)//如果找不到新的缓冲轨,那么输出ERROR,结束循环

                {

                    cout<<"ERROR!"<<endl;

                    flag_end = 1;//结束循环的标志

                    break;

                }

            }

        }

        if(flag_end == 1)//退出while循环

        {

            break;

        }

        //遍历所有非空轨道队头车厢号,如果等于要出队的车厢号,就出轨并且重新循环

        for(int
i = 0 ; i < k ; i++)

        {

            if(!dusk[i].isEmpty()&&dusk[i].showfront()==nowOut)

            {

                cout<<dusk[i].showfront()<<" train by trace "<<i+1<<" out."<<endl;

                dusk[k+1].inQueue(dusk[i].showfront());

                dusk[i].outQueue();

                nowOut++;

                i = -1;

            }

        }

    }

    dusk[k+1].printf();//打印出轨车厢顺序

}

  

火车车厢重排问题--队列模拟,布布扣,bubuko.com

时间: 2024-10-21 04:13:29

火车车厢重排问题--队列模拟的相关文章

火车车厢重排调度

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

火车车厢重排问题

问题描述:一列货运火车从出发站出发时火车上一共有n节车厢,编号分别是1到n.运货的各节车厢是在入轨上时是随机的顺序,火车头在出轨处,现在要将各节车厢按编号从大到小挂到车头上,其中在入轨与出轨之间有k条缓冲铁轨,将通过缓冲铁轨完成本次的火车车厢的重排. 具体规则: 一.车厢从入轨的前部(即右端)只可以移动到一个缓冲铁轨的顶端或出轨的右端. 二.缓冲铁轨的顶端的车厢只可以移动到出轨的最左端 三.车厢不能从一个缓冲铁轨移动到另一个缓冲铁轨或者再移动到入轨 四.车厢移动到出轨的最左端(即火车头端)后不能

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

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

用两个队列模拟实现一个栈的过程

栈具有"后进先出"的特点,即某个元素最后进入栈,却最先出栈:队列具有"先进先出"的特点,即元素从队尾依次进队列,依次从队头出队列:现在用两个队列模拟实现一个栈的过程,详细过程请看下面这张本人制作的gif图: 实现代码: #include <iostream> using namespace std; #include <queue> template <typename T> class Stack { public: void

Codeforces 704A Thor 队列模拟

题目大意:托尔有一部手机可执行三种操作 1.x APP产生一个新消息 2.读取x App已产生的所有消息 3.读取前t个产生的消息 问每次操作后未读取的消息的数量 题目思路: 队列模拟,坑点在于竟然卡内存……详细看代码. #include<iostream> #include<algorithm> #include<cstring> #include<vector> #include<stdio.h> #include<stdlib.h&g

用队列模拟基数排序

function Queue() { //用队列模拟基数排序对应的Queue构造函数中的方法一个都不能少,否则会出错 this.dataStore = []; this.enqueue = enqueue; this.dequeue = dequeue; this.empty = empty; } function enqueue(element) {//向队尾添加一个元素 this.dataStore.push(element); } function dequeue() {//删除队首的元素

栈模拟队列 队列模拟栈

代码如下: PS:做了一些测试,目前没问题.有问题请指正... 栈模拟队列 队列模拟栈

两个栈模拟一个队列和两个队列模拟一个栈

此为网易的一道笔试题.到时候秀逗,不知所云.后来研究之后记录下,以备以后经常翻阅. 栈:先进后出 push和pop 队列:先进先出 offer和poll (1)两个栈模拟一个队列 即将先进后出实现先进先出.比较容易理解,只要所有数据先往一个栈里push,然后将该栈中的数据依次pop出来再push进第二个队列,则顺序自然颠倒过来了,则每次pop是从第二个队列中取数据. import java.util.*; public class StackQueue{ private Stack<Intege

NYOJ714 Card Trick 【队列模拟】

Card Trick 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 The magician shuffles a small pack of cards, holds it face down and performs the following procedure: The top card is moved to the bottom of the pack. The new top card is dealt face up onto the table.