火车车厢重排问题(栈)

问题描述:原文
一列货运列车共有n节车厢,每节车厢将停放在不同的车站。假定n个车站的编号分别为1~n,货运列车按照第n站至第1站的顺序经过这些车站。车厢编号与他们的目的地一样。为了便于从列车上卸掉相应的车厢,必须重排车厢顺序,使得各车厢从前往后按编号1到n的次序排列。当所有车厢按照这种次序排列时,在每个车站只需卸掉最后一个车厢即可。我们在一个转轨站里完成重排的工作,在转轨站有一个入轨,一个出轨和k个缓冲轨(位于入轨和出轨之间)。下面的图示就是一个转轨站,其中有3个缓冲轨,H1,H2,H3。
在这里插入图片描述开始的时候,n节车厢从入轨处进入转轨站,转轨结束时各车厢从右往左按编号1到n的次序离开转轨站。如上图所示。

算法描述:为了重排车厢,需从前往后依次检查入轨上的所有车厢。如果正在检查的车厢就是下一个满足要求的车厢,可以直接把它放到出轨上。否则,则把它移动到缓冲轨上,直到按输出顺序要求轮到它的时候才可以将他放到出轨上。缓冲轨是按照栈的方式使用的,因为车厢的进出都是在缓冲轨的顶端进行的。
在重排车厢过程中,仅允许以下活动:

1、车厢可以从入轨的前部移动到一个缓冲轨的顶部或者是出轨的左端
2、车厢可以从一个缓冲轨的顶部移动到出轨的左端

代码实现:

    class Program
    {
        static bool RailRoad(int[] p, int k)//p指原来车厢的顺序,k是缓冲轨的数量。
        {
            LinkStack<int>[] BufferRail = new LinkStack<int>[k];
            for (int i = 0; i < k; i++)
            {
                BufferRail[i] = new LinkStack<int>();//分配存储空间
            }

            int NowOut = 1;//NowOut指的是现在轮到几号车厢出轨
            int minH = int.MaxValue;//minH指的是在缓冲轨内的车厢的最小编号。
            int minS = -1;//minS指的是minH对应的BufferRail里面的哪条缓冲轨

            for (int i = 0; i < p.Length; i++)
            {
                if (p[i] == NowOut)
                {
                    Console.WriteLine("移动车厢:{0}从入轨到出轨", p[i]);
                    NowOut++;

                    while (minH == NowOut)//若全部的缓冲轨均为空的话,则不会进入到该循环。
                    {
                        Console.WriteLine("移动车厢:{0}从缓冲轨{1}到出轨", minH, minS);
                        OutStack(ref minH, ref minS, BufferRail);//最主要的作用就是更新minH和minS                        
                        NowOut++;
                    }
                }
                else
                {
                    bool result = EnterStack(p[i], ref minH, ref minS, BufferRail);
                    if (result == false)
                    {
                        return false;
                    }
                }
            }

            return true;
        }

        static void OutStack(ref int minH, ref int minS, LinkStack<int>[] BufferRail)
        {
            BufferRail[minS].Pop();//出栈

            minH = int.MaxValue;
            minS = -1;
            for (int i = 0; i < BufferRail.Length; i++)
            {
                if (BufferRail[i].IsEmpty() == false)
                {
                    if (BufferRail[i].StackTop < minH)
                    {
                        minH = BufferRail[i].StackTop;
                        minS = i;
                    }
                }
            }
        }

        static bool EnterStack(int c, ref int minH, ref int minS, LinkStack<int>[] BufferRail)
        {
            //参数c代表要进入的车厢的编号。
            int bestTrack = -1;//c号车厢能进入的最优缓冲轨
            int bestTop = int.MaxValue;//c号车厢进出前,bestTrack对应的栈顶元素。
            for (int i = 0; i < BufferRail.Length; i++)
            {
                if (BufferRail[i].IsEmpty())
                {
                    bestTrack = i;
                    break;
                }
                else
                {
                    int x = BufferRail[i].StackTop;
                    if (c < x && x < bestTop)
                    {
                        bestTop = x;
                        bestTrack = i;
                    }
                }
            }

            if (bestTrack == -1)//说明c号车厢无轨可进
            {
                return false;
            }
            else
            {
                BufferRail[bestTrack].Push(c);
                Console.WriteLine("移动车厢:{0}从入轨到缓冲轨{1}", c, bestTrack);
                if (c < minH)
                {
                    minH = c;
                    minS = bestTrack;
                }
                return true;
            }
        }
        static void Main(string[] args)
        {
            int[] p = { 3, 6, 9, 2, 4, 7, 1, 8, 5 };
            int k = 1;
            bool result = RailRoad(p, k);
            while (result == false)
            {
                Console.WriteLine("需要更多的缓冲轨,请输入增加的数量:");
                k = k + Convert.ToInt32(Console.ReadLine());
                result = RailRoad(p, k);
            }
        }
    }
移动车厢:3从入轨到缓冲轨0
需要更多的缓冲轨,请输入增加的数量:
2
移动车厢:3从入轨到缓冲轨0
移动车厢:6从入轨到缓冲轨1
移动车厢:9从入轨到缓冲轨2
移动车厢:2从入轨到缓冲轨0
移动车厢:4从入轨到缓冲轨1
移动车厢:7从入轨到缓冲轨2
移动车厢:1从入轨到出轨
移动车厢:2从缓冲轨0到出轨
移动车厢:3从缓冲轨0到出轨
移动车厢:4从缓冲轨1到出轨
移动车厢:8从入轨到缓冲轨0
移动车厢:5从入轨到出轨
移动车厢:6从缓冲轨1到出轨
移动车厢:7从缓冲轨2到出轨
移动车厢:8从缓冲轨0到出轨
移动车厢:9从缓冲轨2到出轨
  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
一列货运列车共有 n 节车厢,每节车厢将停放在不同的车站。假定 n 个车站的编号分别 为 1~n,车厢的编号与它们的目的地相同。货运列车按照从第 n 站至第 1 站的次序经过这 些车站。为了便于从列车上卸掉相应的车厢,必须重新排列车厢,使各车厢从前至后按编号 1~n 的次序排列。当所有的车厢按照这种次序排列时,在每个车站只卸掉最后一节车厢 即可。可以在一个转轨站里完成车厢重排工作,在转轨站中有一个入轨,一个出轨和k 个缓冲铁轨(位于入轨和出轨之间)。 图 3-1 给出了一个转轨站, 其中有 k=3 个缓冲铁轨 H1,H2 和 H3。开始时,n节车厢的货车从入轨处进入转轨站,车厢重排结束时各车厢按照编号1至编号n的次序从出轨处离开转轨站。在图 3-1(a)中,n=9,车厢从后至前的初始次序为 5,8,1,7,4,2,9,6,3。图 3-1(b)给出按所要求的次序重新排列后的结果。 为了重排车厢,从前至后依次检查入轨上的所有车厢。如果正在检查的车厢就是下一个满足排列的要求的车厢,可以直接把它放到出轨上。如果不是,则把它移动到缓冲铁轨上, 直到按输出次序要求轮到它时才将它放到出轨上。由于缓冲铁轨上车厢的进和出都是在其顶 部进行的,因此缓冲铁轨是按照 LIFO 的方式使用的。在重排车厢过程中,仅允许以下移动:  车厢可以从入轨移动到一个缓冲铁轨的顶部或者出轨上;  车厢可以从一个缓冲铁轨的顶部移动到的出轨上;

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奇迹luanluan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值