问题 G: 车站调度

前言必读!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");
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值