02-线性结构4 Pop Sequence分数 25

题目

02-线性结构4 Pop Sequence    分数 25    作者 陈越          单位 浙江大学

给定一个可以保持的堆栈M最多数字。推N数字按 1、2、3、...、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”。

示例输入:

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

示例输出:

YES
NO
NO
YES
NO

题解:

#include <stdio.h>
#include <stdbool.h>

typedef struct {
    int capacity;
    int stack[1000];
    int top;
} Stack;

void initStack(Stack *s, int capacity) {
    s->capacity = capacity;
    s->top = -1;
}

void push(Stack *s, int num) {
    if (s->top < s->capacity - 1) {
        s->stack[++(s->top)] = num;
    }
}

int pop(Stack *s) {
    if (s->top >= 0) {
        return s->stack[(s->top)--];
    }
    return -1;
}

bool isPossiblePopSequence(int M, int N, int sequence[]) {
    Stack s;
    initStack(&s, M);
    int currentPush = 1;
    
    for (int i = 0; i < N; i++) {
        while (currentPush <= sequence[i]) {
            push(&s, currentPush++);
        }
        int popped = pop(&s);
        if (popped != sequence[i]) {
            return false;
        }
    }
    
    return true;
}

int main() {
    int M, N, K;
    scanf("%d %d %d", &M, &N, &K);
    
    for (int i = 0; i < K; i++) {
        int sequence[1000];
        for (int j = 0; j < N; j++) {
            scanf("%d", &sequence[j]);
        }
        
        if (isPossiblePopSequence(M, N, sequence)) {
            printf("YES\n");
        } else {
            printf("NO\n");
        }
    }
    
    return 0;
}

当涉及堆栈和代码逻辑时,理解可能需要更详细的解释。我会逐步解释我提供的代码,帮助你更好地理解每一部分。

定义结构体

typedef struct {
    int capacity;
    int stack[1000];
    int top;
} Stack;

这段代码定义了一个结构体 Stack,它表示一个堆栈数据结构。这个结构体有三个成员变量:

  • int capacity: 表示堆栈的容量,即能够容纳的最大元素数量。
  • int stack[1000]: 一个整型数组,用来存储堆栈的元素。
  • int top: 表示堆栈的顶部元素的索引。

initStack 函数初始化堆栈:

void initStack(Stack *s, int capacity) {
    s->capacity = capacity;
    s->top = -1;
}
这个函数接受一个指向 Stack结构体的指针 s,以及堆栈的容量 capacity。它将 capacity赋值给堆的capacity成员,并将 top初始化为 -1,表示堆栈为空。

push 函数将元素推入堆栈:

void push(Stack *s, int num) {
    if (s->top < s->capacity - 1) {
        s->stack[++(s->top)] = num;
    }
}

这个函数接受一个指向 Stack 结构体的指针 s,以及要推入堆栈的元素 num。它首先检查堆栈是否还有空间(s->top < s->capacity - 1),如果有空间,则将 num 推入堆栈中,并将 top 值递增。

pop 函数从堆栈中弹出元素:

 
int pop(Stack *s) {
    if (s->top >= 0) {
        return s->stack[(s->top)--];
    }
    return -1;
}

 

这个函数接受一个指向 Stack 结构体的指针 s。它首先检查堆栈是否非空(s->top >= 0),如果非空,则返回堆栈顶部元素的值,并将 top 值递减。

判断堆栈

最后,isPossiblePopSequence 函数用来判断给定的弹出序列是否可能是堆栈的弹出序列:

 
bool isPossiblePopSequence(int M, int N, int sequence[]) {
    Stack s;
    initStack(&s, M);
    int currentPush = 1;
    
    for (int i = 0; i < N; i++) {
        while (currentPush <= sequence[i]) {
            push(&s, currentPush++);
        }
        int popped = pop(&s);
        if (popped != sequence[i]) {
            return false;
        }
    }
    
    return true;
}

 

这个函数接受堆栈的最大容量 M,弹出序列的长度 N,以及表示弹出序列的整型数组 sequence[]。它首先初始化一个堆栈 s,然后遍历弹出序列。对于每个弹出序列的元素,它会将元素依次推入堆栈,然后尝试弹出元素,如果弹出的元素与序列中的元素不匹配,则返回 false。如果所有的元素都能够正确弹出,并且没有不匹配的情况,则返回 true,表示这个弹出序列是合法的。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

非黑皆白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值