浙江大学数据结构MOOC-课后习题-第二讲-线性结构4 Pop Sequence

题目汇总
浙江大学数据结构MOOC-课后习题-拼题A-代码分享-2024

题目描述

给定一个最多可以保留 M 个数字的堆栈。按 1、2、3、…、N 的顺序推送 N 个数字并随机弹出。您应该判断给定的数字序列是否是堆栈的可能弹出序列。例如,如果 M 是 5,N 是 7,我们可以从堆栈中得到 1、2、3、4、5、6、7,但不能得到 3、2、1、7、5、6、4。

输入规格:
每个输入文件都包含一个测试用例。对于每种情况,第一行包含 3 个数字(均不超过 1000):M(堆栈的最大容量)、N(推送序列的长度)和 K(要检查的弹出序列数)。然后是 K 行,每行都包含 N 个数字的弹出序列。一行中的所有数字都用空格分隔。

输出规格:
对于每个弹出序列,如果它确实是堆栈的可能弹出序列,则在一行中打印“YES”,如果不是,则打印“NO”。

Sample Input:

5 7 5
1 2 3 4 5 6 7
3 2 1 7 5 6 4
7 6 5 4 3 2 1
5 6 4 3 7 2 1
1 7 6 5 4 3 2

Sample Output:

YES
NO
NO
YES
NO

代码展示
本题的思路是,将元素按1,2,3…N的顺序入栈,并且按照题目所给的序列来出栈(采用的方法是:每次入栈一个元素后,检查栈顶元素是否是题目所给序列中的当前出栈元素,若是则出栈)
如果最后栈为空,那么说明题目所给序列是合法的,否则不合法

#include <stdio.h>

#define MAXSIZE 1000
typedef struct stack
{
    int a[MAXSIZE];
    int top;
} stack;

void clearStack(stack* s)
{
    s->top = -1;
}
void push(stack* s, int e)
{	
    s->a[++s->top] = e;
}
int pop(stack* s)
{
    int e = s->a[s->top];
    s->top--;
    return e;
}

int isEmpty(stack* s)
{
    if (s->top == -1) return 1;
    else return 0;
}

int main()
{
    int M, N, K;	//M:堆栈的最大容量 N: 推送序列的长度 K:共有K行数据
    scanf("%d %d %d", &M, &N, &K);
    int res[MAXSIZE] = { -1 };
    stack s;
    s.top = -1;
    for(int count = 0; count < K; count++)
    {	
        clearStack(&s);
        int cur = 0;				//出栈序列当前元素位置
        int out[MAXSIZE] = { 0 };	//存储出栈序列
        //将出栈序列存入out数组
        for (int i = 0; i < N; i++)
        {
            scanf("%d", &out[i]);
        }
        //按照入栈序列的顺序,依次将元素压入辅助栈。
        for (int i = 1; i <= N; i++)
        {	
            if (s.top < M - 1)
            {
                push(&s, i);
            }
            //压入后,检查栈顶元素是否与出栈序列当前指针指向的元素相同
            //如果相同,则将该元素出栈,且指针向后移动一位。
            while (!isEmpty(&s) && s.a[s.top] == out[cur])
            {
                pop(&s);
                cur++;
            }
        }
        //先将结果统一保存到数组中,最后再集中打印
        if (isEmpty(&s))
        {
            res[count] = 1;
        }
        else
        {
            res[count] = 0;
        }
    }
    for (int i = 0; i < K; i++)
    {
        if (res[i] == 1)
        {
            printf("YES\n");
        }
        if (res[i] == 0)
        {
            printf("NO\n");
        }
    }
    return 0;
}
  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值