算法竞赛入门经典:第六章 数据结构基础 6.2铁轨

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

输入:
5
1 2 3 4 5
5 
5 4 1 2 3
6
6 5 4 3 2 1
输出:
Yes
No
Yes
*/
#include <stdio.h>
#include <stdlib.h>
#include <stack>

using namespace std;

#define MAXSIZE 1024

void rail()
{
	int n;
	while(EOF != scanf("%d",&n))
	{
	stack<int> stackIntRail;
	/*
	for(int i = 1; i <= n; i++)
	{
		stackIntRail.push(i);
	}
	*/
	int iArr[MAXSIZE];
	int k = 1;
	int nCopy = n;
	while(n--)
	{
		scanf("%d",&iArr[k++]);
	}
	int iCount = 1;//专门用来过滤相同的前缀,例如:1 2 3 4 5
	int iPos = 1;
	bool isRight = true;
	while(iPos <= nCopy)
	{
		if(iCount == iArr[iPos])//解决顺序输出的问题,一旦iCount超过栈的大小,就不走这个分支
		{
			iPos++;
			iCount++;
		}
		//else if(stackIntRail.top() == iArr[iPos])
		else if(!stackIntRail.empty() && stackIntRail.top() == iArr[iPos])//解决一一比较的问题,每次总是拿数组元素与栈元素比较大小
		{
			stackIntRail.pop();
			iPos++;
		}
		else if(iCount <= nCopy)//针对逆序问题,将元素压入栈中,为第二个分支比较做准备
		{
			stackIntRail.push(iCount++);
		}
		else
		{
			isRight = false;
			break;
		}
	}
	isRight ? puts("Yes") : puts("No");
	}
}

void rail_repeat()
{
	int n;
	int iArr[MAXSIZE];
	while(EOF != scanf("%d",&n))
	{
		for(int i = 0 ; i < n;i++)
		{
			scanf("%d",&iArr[i+1]);
		}
		int iPos = 1,iCount = 1;//iPos用于标记输入数组,iCount用于计数
		stack<int> stackInt;
		bool isRight = true;
//		while(iCount <= n)
		while(iPos <= n)
		{
			if(iArr[iPos] == iCount)//解决顺序问题
			{
				iPos++;
				iCount++;
			}
			else if(!stackInt.empty() && stackInt.top() == iArr[iPos])//解决比较问题,始终拿栈顶和数组前面的元素比较,因为相消必定拿前面的
			{
				stackInt.pop();
				iPos++;
			}
			//else if(iPos <= n)//解决逆序问题
			else if(iCount <= n)
			{
			//	stackInt.push(iPos++);
				stackInt.push(iCount++);
			}
			else
			{
				isRight = false;
				break;
			}
		}
		isRight ? puts("Yes") : puts("No");
	}
}

//模拟栈,不像队列,只需要栈顶指针,top=0表示栈空
void rail(int i,int j)
{
	int n;
	while(EOF != scanf("%d",&n))
	{
		int m_stack[MAXSIZE];//栈必须放进循环中
		int iArr[MAXSIZE];
		int top = 0;
		for(int i = 0 ; i < n ; i++)
		{
			scanf("%d",&iArr[i+1]);
		}
		int iPos = 1,iCount = 1;
		bool isRight = true;
		while(iPos <= n)
		{
			if(iCount == iArr[iPos])
			{
				iPos++;
				iCount++;
			}
			else if(top && m_stack[top] == iArr[iPos])
			{
				top--;
				iPos++;
			}
			else if(iCount <= n)
			{
		//		m_stack[top++] = iCount;
				//m_stack[++top] = iCount;//加送取减栈,栈要先加,m_stack[1]为栈底元素,iCount
				m_stack[++top] = iCount++;
			}
			else
			{
				isRight = false;
				break;
			}
		}
		isRight ? puts("Yes") : puts("No");
	}
}

int main(int argc,char* argv[])
{
	//rail_repeat();
	rail(1,1);
	system("pause");
	return 0;
}

你可能感兴趣的:(栈)