1

题目大意:

现有容量为M的栈,入栈序列是1到N,现有K个长度为N的出栈序列,请问是否按照固定的入栈序列是否可以通过出栈获得输入的出栈序列

算法思路:

第一个就是得看清楚题目,题目说的是入栈序列为1到N,意思是入栈的顺序得按照1到N进行输入,在输入的时候可以有出栈操作。然后我们选择
STL库中的stack<int> s作为我们的操作数栈,使用pop_num保存当前待比较的出栈序列的元素(需要输入),然后在每一次的查询过程中,用isPossible记录当前查询的出栈序列是否合法,初始为true,使用push_num记录待入栈的元素(和栈顶元素没有什么关系),接来下就是具体的比较操作,我们首先将栈清空,这里也可以选择将栈的定义写在循环体内部,对于每一次输入的pop_num,如果push_num<=pop_num,说明待出栈元素还没有入栈,得先依次入栈所有小于等于pop_num的元素,如果栈的容量无法加入需要入栈的元素,那么就让isPossible置为false,并且终止程序继续运行,否则就模拟入栈过程,并且出栈栈顶元素,如果push_num>pop_num,说明待出栈元素已经入栈,那么就只需要出栈栈顶元素,然后比较和pop_num是否相等,如果不相等就让isPossible置为false,并且终止程序继续运行。最后在所有数字输入完毕后判断isPossible,为true输出YES,否则输出NO.

注意点:

1、这里由于是使用的pop_num接受每一个待比较的数字,所以在isPossible置为false后不能退出循环,得使用continue,并且在接受pop_num后,只要isPossiblefalse,就继续循环,不让程序往下执行。
2、每次比较的时候栈得清空并且push_num每次都得置为1.

提交结果:

图片.png

AC代码1:

#include<cstdio>
#include<stack>

using namespace std;

stack<int> s;

int main(){
    int M,N,K;//栈的容量,入栈序列长度,比较的序列个数
    scanf("%d %d %d",&M,&N,&K);
    int pop_num;// 当前待比较的出栈序列的元素 
    for(int i=0;i<K;++i){
        bool isPossible = true;
        int push_num = 1;//待入栈的元素
        if(i!=0){
            // 每次都得清空栈的元素 
            while(!s.empty()){
                s.pop();
            }
        }
        for(int j=0;j<N;++j){
            scanf("%d",&pop_num);
            if(!isPossible){
                continue;
            }
            if(push_num<=pop_num){
                if(pop_num-push_num+1>M-s.size()){
                    // 需要进栈的元素个数超过栈的剩余容量 
                    isPossible = false;
                    continue;
                }
                // 栈可以容入需要入栈的元素 
                while(push_num<=pop_num){
                    // 入栈 
                    s.push(push_num);
                    ++push_num;
                }
                // 出栈 
                s.pop();
                // 这里不用判断出栈的元素和出栈序列中需要比较的元素是否相等 
            }else {
                //出栈
                int top_num = s.top();
                s.pop();
                if(top_num!=pop_num){
                    isPossible = false;
                    continue;
                }
            }
        }
        if(isPossible){
            printf("YES\n");
        }else{
            printf("NO\n");;
        }
    } 
    return 0; 
}
上面的写法必须得接收完毕所有的pop_num,否则程序会停止,这里给出另外一种方法,使用数组先接收所有待比较的出栈序列,然后在进行查询。

AC代码2:

#include<cstdio>
#include<stack>
#include<cstring>

using namespace std;

int main(){
    int M,N,K;//栈的容量,入栈序列长度,需要判断的序列个数
    scanf("%d %d %d",&M,&N,&K);
    int num;
    for(int i=0;i<K;++i){
        bool flag = true;//判断当前序列是否可以输出
        stack<int> s;
        int num = 1;//当前需要入栈的元素
        int a[N];
        for(int j=0;j<N;++j){
            scanf("%d",&a[j]);
        } 
        for(int j=0;j<N;++j){
            int temp = a[j];//当前需要出栈的元素
            while(num<=temp){//将num到temp的元素全部进栈 
                s.push(num);
                if(s.size()>M){
                    flag = false;
                    break;
                }
                ++num;
            } 
            if(!flag) break;//栈溢出 
            int k = s.top();
            if(k!=temp){
                flag = false;//num>temp并且栈顶元素和出栈元素不同 
                break;
            }else{
                s.pop();//相同,则出栈 
            }
        }
        if(!flag){
            printf("NO\n");
        }else{
            printf("YES\n");
        }    
    } 
    return 0;
} 

乔梓鑫
569 声望17 粉丝

主要分享个人学习经验和心得