铁轨(rails,ACM/ICPC CERC 1997,UVa 514)

今天学习算法:发现自己对栈很懵逼,看了一下程序,决定自己手动写一遍加深理解。

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

思路: 
在中转站C中,车厢符合后进先出的原则,因此是一个栈。我们只能对其进行入栈和出栈的操作 
1.当序列中的元素和栈顶元素相同时,进行下一个元素的判断。不是的话,那就需要进行下一步的判断了。 
2. 判断序列中的元素是否和输入的序列中即将入栈的那个元素相同,是的话对下一个元素进行判断,不是的话,进行下一步。 
3. 判断输入序列是否可以入栈,可以的话,将输入序列当前的第一个入栈,不可以的话,进入下一步。 
4. 跳出循环,不能得到给定的输出序列。

#include<cstdio>
#include<iostream>
#include<strack>
using namespace std;
const int MAXN=1000+10;
int n,arr[MAXN]; 

int main()
{
	while(scanf("%d",&n)==1){
		stack<int> s;
		for(int i=1;i<n;i++)
			scanf("%d",&arr[i]); 
		int ok=1; 
		int A=1,B=1;
		while(B<=n) 
		{
			if(A==arr[B]){
				A++;B++;			//second:如果进出顺序相同,则不必使用栈 ,当A=5时,第五节车厢不进入栈,直接出来 
			}else if (!s.empty&&s.top()==arr[B]){//third:一直扔出 
				s.pop();
				B++; 
			} else if(A<=n){		//first:建立栈:一直扔直到A=5; 
				s.push(A++); 
			} else {//检查部分:如果不能通过栈的方式扔出  终止循环,并且ok为0 
				ok=0;
				break;
			} 
		} 
		printf("%s",ok?"yes":"no") ; 
	} 
} 

大概就是这个样子,仔细理解while循环;

(代码自己手动的,题目是复制一位大佬的,)

猜你喜欢

转载自blog.csdn.net/xizi_ghq/article/details/81112093