前言必读!http://blog.csdn.net/hnust_v/article/details/51747743
问题 G: 车站调度
题目描述
有顺序排列的1,2, 3,…,n节车厢在入站口等待调度。车站设置了一个栈作为缓冲,这样的话只可能进行下列两个操作之一:
(1)如果还有车厢在入站口,将最前面的入栈缓冲
(2)将栈顶的车厢驶出车站
给定一个1至n的排列,问其作为出站序列是否合法。
注意:入站顺序为1,2, 3,…,n,即1先入栈…,n最后入栈。
输入
输入包含若干测试用例。每一个测试用例由多行组成。第一行是两个整数n(1<=n <= 100)和m,n表示入站序列为1至n。m表示随后有m行出站序列。
当n,m均为0时表示输入结束。
输出
对应每一个出站序列,合法则输出一行YES,否则输出一行NO。
//思路:反题意考虑所给序列能不能通过车站(栈)还原成 n,n-1,n-2,……1序列
令i=n
第一步 应当让i先出站
判断 i是否为0
是 返回正确
不是 执行第二步
第二步 判断当前最后一辆是不是i?
是
i=i-1
执行第三步
第三步 判断栈顶元素是不是i
是
i出栈
i=i-1
执行第四步
不是 执行第四步
第四步 判断当前车站(栈)是否为空
是
将i压入栈内
i=i-1并且返回第一步
不是
判断栈顶元素是否比当前最后一辆序列大
是 返回错误 //因为若序号低的压在序号高的上面就无法先输出序号高的,必然是错误的
不是 将最后一辆序号压入栈内
i=i-1并且返回第一步
伪代码描述 :
Judge (n, stack<int> S): //stack请按书实现功能 或者使用 C++ STL
need=n
for i=n to 1
if A[i] = need
need = need -1
while !S.empty() and S.top = need
S.pop()
need = need -1
continue
if S.empty()
S.push(A[i])
else
if S.top() > A[i]
return false
else S.push(A[i])
return true
//C++:
#include <bits/stdc++.h>
using namespace std;
int A[3000];
int Judge(int n)
{
stack<int> S;
int now=n;
for(int i=n;i>=1;i--)
{
if(A[i]==now)
{
now--;
while(!S.empty()&&S.top()==now)
{
S.pop();
now--;
}
continue;
}
// if(!S.empty()) cout<<S.top()<<endl;
if(S.empty()) S.push(A[i]);
else
{
if(S.top()>A[i]) return 0;
else S.push(A[i]);
}
}
return 1;
}
int main()
{
//freopen("F:\\test.txt","r",stdin);
int n,m;
while(~scanf("%d %d",&n,&m)&&(n||m))
{
for(int k=1;k<=m;k++)
{
for(int i=1;i<=n;i++) scanf("%d",&A[i]);
// printf("\nCase %d\n",k);
printf("%s\n",Judge(n)?"YES":"NO");
}
}
}