[poj1363]Rails_模拟_栈

Rails poj-1363

    题目大意:判断一个序列是否是1~n的合法出栈序列。

    注释:$1le nle 10^4$。

      想法:开始想到一种想法。

        对于一段序列来讲,显然从首元素开始的连续小于尾元素的序列必定为合法出栈序列,所剩下的数所组成的序列也必为合法出栈序列。

      黄色序列中所有数小于尾元素,不小于全序列最小值(废话),而且必定为全队最小值到尾元素-1的一个排列。绿色序列同理

      然后,我们递归处理,先判断前面的黄色序列是否是合法的全排列,绿色序列是否是合法的全排列,然后递归处理。

      但是,EdwardFrog有一种更显然的方法。我们进行模拟:

        根据题目中的要求,如果当前第i个数小于等待进栈的数,显然它仍在栈里,如果栈首不是它,整个序列就是不合法的。反之,弹出。

                如果第i个数大于等待进栈的数,我们连续的进栈,使得它刚好是栈首,此时弹出。

        时间复杂度O(n)

    最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
int sta[1010];
int a[1010];
int head,k;
void original()
{
	memset(sta,0,sizeof sta);
	memset(a,0,sizeof a);
	head=0;
	k=1;
}
int main()
{
	int n;
	while(~scanf("%d",&n))
	{
		if(!n) return 0;
		// int n;
		// cin >> n;
		while(1)
		{
			original();
			bool nxt=false;
			for(int i=1;i<=n;i++)
			{
				scanf("%d",&a[i]);
				if(a[i]==0)
				{
					nxt=true;
					break;
				}
			}
			if(nxt) break;
			bool flag=true;
			for(int i=1;i<=n;i++)
			{
				if(a[i]<k)
				{
					if(sta[head]!=a[i])
					{
						printf("No
");
						flag=false;
						break;
					}
					else
					{
						head--;
						continue;
					}
				}
				else if(a[i]==k) k++;
				else
				{
					while(k<=a[i])
					{
						sta[++head]=k;
						k++;
					}
					head--;
				}
			}
			if(flag)printf("Yes
");
		}
		puts("");
	}
	return 0;
}

     小结:想到一个不可描述,但是觉得贼牛逼的做法时,不妨往简单想一想,毕竟所有的题目都是有简单的点构成的。

原文地址:https://www.cnblogs.com/ShuraK/p/8743536.html