火车入轨_算法

【问题描述】

  某城市有一个火车站,铁轨铺设如图所示。有n节车厢从A方向驶入车站,按进站顺序编号为1~n。你的任务是让它们按照某种特定的顺序进入B方向的铁轨并驶出车站。为了重组车厢,你可以借助中转站C。这是一个可以停放任意多节车厢的车站,但由于末端封顶,驶入C的车厢必须按照相反的顺序驶出。对于每个车厢,一旦从A移入C,就不能再回到A了;一旦从C移入B,就不能回到C了。换句话说,在任意时刻,只有两种选择:A→C和C→B。

 

这个问题和之前数据结构实验的火车入轨类似,而且较之简化。自己尝试写了下,和书上参考答案的代码量仍有较大差距。代码如下:

 1 #include<iostream>
 2 using namespace std;
 3 const int MAXSIZE=100;
 4 void main()
 5 {
 6     int n;
 7     cin>>n;
 8     int a[MAXSIZE],b[MAXSIZE];
 9     int stack[MAXSIZE];
10     for(int i=0;i<n;i++)
11     {
12         a[i]=i+1;
13         cin>>b[i];                      //出栈顺序
14     }
15     int top=-1;
16     int count=0;
17     int i=0;
18     for(;;)
19     {
20         if(i<n)
21         {
22             ++top;
23             stack[top]=a[i++];            //入栈
24             cout<<"PUSH"<<endl;
25         }
26     
27         if(stack[top]==b[count])
28         {
29             top--;count++;
30             cout<<"POP"<<endl;
31         }
32         else if(i==n)
33         {
34             cout<<"NO"<<endl;
35             break;
36         }
37         if(count==n)
38         {
39             cout<<"YES"<<endl;
40             break;
41         }
42         if(top<-1)
43         {    
44             cout<<"NO"<<endl;
45             break;
46         }
47     }
48 
49 }

 书中参考代码如下:

 1 #include<iostream>
 2 using namespace std;
 3 const int MAXN=1000+10;
 4 int n,target[MAXN];
 5 void main()
 6 {
 7     while(cin>>n)
 8     {
 9         int stack[MAXN],top=0;
10         int A=1,B=1;                                              //A用来记录入栈次数,B用来记录出轨的火车序号
11         for(int i=1;i<=n;i++)
12             cin>>target[i];                                        //记录出轨顺序
13         int ok=1;
14         while(B<=n)
15         {
16             if(A==target[B]){A++;B++;}
17             else if(top && stack[top]==target[B]){top--;B++;}      //出栈
18             else if((A<=n)) stack[++top]=A++;                      //入栈
19             else {ok=0;break;}
20         }
21         if(ok)
22             cout<<"Yes"<<endl;
23         else
24             cout<<"No"<<endl;
25     }

同样,可以用STL来实现,只需对书中参考答案作微小改动,代码如下:

 1 /*STL栈来实现*/
 2 #include<iostream>
 3 #include<stack>
 4 using namespace std;
 5 const int MAXN=1000+10;
 6 int n,target[MAXN];
 7 int main()
 8 {
 9     while(cin>>n)
10     {
11         stack<int> s;
12         int A=1,B=1;
13         for(int i=1;i<=n;i++)
14             cin>>target[i];
15         int ok=1;
16         while(B<=n)
17         {
18             if(A==target[B]){A++;B++;}
19             else if(!s.empty() && s.top()==target[B]){s.pop();B++;}
20             else if(A<=n) s.push(A++);
21             else {ok=0;break;}
22         }
23         if(ok)
24             cout<<"YES"<<endl;
25         else
26             cout<<"NO"<<endl;
27     }
28 }

【总结】

  自己写的代码仍有优化的空间。学习参考答案的清晰逻辑的表达。学习STL栈的使用。

  联系数据结构实验中关于火车入轨的提升,对缓冲轨的限制,应该增加一个判断即可。

转载于:https://www.cnblogs.com/anthozoan77/p/3464363.html

一列货运列车共有 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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值