【PTA】Pop Sequence

//第一版:判定条件略多
#include <iostream>
#include <stack>
#define MAXN 1010
using namespace std;

//模拟栈和需要判定的序列
stack<int> s;
int a[MAXN];


int main(){
    int M,N,K;
    scanf("%d %d %d",&M,&N,&K);

int index=0,flag=1;
int tmp=1;
for(int j=0;j<K;j++){
    flag=1;
    index=0;
    tmp=1;
    s.push(1);
    //读入序列
    for(int k=0;k<N;k++){
        scanf("%d",&a[k]);
    }
    //判定序列
    while(index<N){
//一直存入顺序数,直到栈顶元素不小于当前需输出的元素
       while(s.top()<a[index]){
//如果存满了还是小于,则序列非法
           if(s.size()<M && s.top()<N){
               s.push(tmp+1);
               tmp++;
           }else{
               flag=0;
               break;
           }
       }
//若大于则序列非法,若等于则删除栈顶元素,index++,进行本轮下一元素输出判定
       if(s.top()==a[index]){
           s.pop();
           index++;
       }else{
           flag=0;
       }

//序列非法直接退出本轮判定
       if(!flag) break;

//若栈空,必须压入下一元素,也有可能是本轮最后一个元素的判定       
       if(s.size()==0){
              if(tmp<N) s.push(tmp+1);
              else break;
        } 
    }

    if(flag==1) printf("YES\n");
    else printf("NO\n");

//清除本轮模拟栈元素
    while(!s.empty()){
        s.pop();
    }
}



    return 0;  
}

//注意:入栈之后才能判定,否则有可能是栈满的非法情况。

//即:只接受入栈之后马上出栈,不接受不入栈的判定

//第二版
#include <iostream>
#define MAXN 1010
#include <stack>
using namespace std;

int main(){
    int M,N,K;
    cin>>M>>N>>K;
    
    int v[MAXN];
    stack <int> s;
    int v1,s1,flag;
    for(int i=0;i<K;i++){
//读入序列
        for(int j=0;j<N;j++) cin>>v[j];
        
        v1=0;s1=1;
        flag=1;
//先入栈:1
        s.push(s1);

//两个临界条件:
//1:v1<N
//2: s1<M (s.size()<M)
        while(v1<N){
//当s.top()<v[v1]时一直push,直到:超过栈大小或s.top()==v[v1]
            while(s.top()<v[v1] && s.size()<M){
                s.push(s1+1);
                s1++;
            }
//如果s.top()==v[v1]则pop()出来,如果超过栈大小,则失败
            if(s.top()==v[v1]){
                s.pop();
                v1++;
            }else{
                flag=0;
                break;
            }
//失败直接退出本轮
            if(!flag) break;
//防止pop之后栈s变空没法while判断
            if(s.size()==0){
                s.push(s1+1);
                s1++;
            }
        }

//不是中途退出则flag==1,中途退出flag==0
        if(flag==1) cout<<"YES\n";
        else        cout<<"NO\n";
//清空本轮的栈
        while(!s.empty()){
            s.pop();
        }
             
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值