PAT 02-4. Pop Sequence (25) Python C

8 篇文章 0 订阅
7 篇文章 0 订阅

02-线性结构4. Pop Sequence (25)

题目要求

Given a stack which can keep M numbers at most. Push N numbers in the order of 1, 2, 3, …, N and pop randomly.
You are supposed to tell if a given sequence of numbers is a possible pop sequence of the stack.
For example, if M is 5 and N is 7, we can obtain 1, 2, 3, 4, 5, 6, 7 from the stack, but not 3, 2, 1, 7, 5, 6, 4.

Input Specification:

Each input file contains one test case. For each case, the first line contains 3 numbers (all no more than 1000):
M (the maximum capacity of the stack), N (the length of push sequence), and K (the number of pop sequences to be checked).
Then K lines follow, each contains a pop sequence of N numbers. All the numbers in a line are separated by a space.

Output Specification:

For each pop sequence, print in one line “YES” if it is indeed a possible pop sequence of the stack, or “NO” if not.

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

题目的意思
栈的大小M,输入序列的长度N(默认序列即为1,2,3…,N),入栈出栈的顺序不定。有K个测试序列,判断每一个测试序列是否是可能的出栈顺序。
核心:从出栈顺序推测入栈顺序

关键点:
在pop t时,那么一定要先push 1,2,3…t-1,t;即要先将小于等于t的数都push入栈才能pop t。在这个过程中检查pop的次数是否等于N以及入栈的数目是否大于栈的容量M

@声明:分析和C语言实现,参考了周大侠的博客。

实现代码

方式一:Python语言:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
'''
Nothing Replaces Hard Work
By:jixiangrurui
Date:2015.08.17
Python:3.4.3
'''
def CheckSeq(check,M,N,K):
    '''(list of str, int, int, int) -> int

    Return the check seq whether is the right order
    >>> check = ['5', '6', '4', '3', '7', '2', '1']
    >>> CheckSeq(check,5,7,5)
    1
    >>> check = ['1', '7', '6', '5', '4', '3', '2']
    >>> CheckSeq(check,5,7,5)
    0
    '''
    stack=[]
    stack.append(0)
    num = 1            # 在pop t时,一定要先push 1,2,3…t-1,t,即要先将小于等于t的数都push入栈才能pop t。
    for i in range(N): # 这个过程中检查pop的次数是否等于N以及入栈的数目是否大于栈的容量M
        while(stack[len(stack)-1] < int(check[i]) and i != N and len(stack) <= M ):
              stack.append(num)
              num = num + 1
        if(stack[len(stack)-1] == int(check[i])):
              stack.pop()
        else:
            return 0

    return 1


if __name__ == '__main__':

    strs = []
    strs = input().split(" ")
    M = int(strs[0])
    N = int(strs[1])
    K = int(strs[2])
    seq = []
    for i in range(K):
        strs = input().split(" ")
        seq.append(strs)
    for i in range(K):
        if(CheckSeq(seq[i],M,N,K) == 1):
            print("YES")
        else:
            print("NO")

这里写图片描述

方式二:C语言

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

#define MaxSize 1000
typedef struct Node
{
    int Data[MaxSize];
    int cap;    //最大容量
    int top;    //size = top + 1
} Stack;

int M,N,K;   //M:最大栈容量  N:入栈序列的长度  K:pop sequence的数目

Stack *CreateStack(){
    Stack *PtrS = (Stack *)malloc(sizeof(Stack));
    PtrS -> cap = MaxSize;
    PtrS -> top = -1;
    return PtrS;
}
void Push(Stack *PtrS,int ele){
    if (PtrS -> top == PtrS -> cap-1)
    {
        printf("FULL");
        return ;
    }
    PtrS -> top++;
    PtrS -> Data[PtrS->top] = ele;
}
int top(Stack *PtrS){
    return PtrS -> Data[PtrS->top];
}
void Pop(Stack *PtrS){
    if(PtrS -> top == -1){
        printf("Empty");
        return ;
    }
    PtrS -> top--;
}
int Check_Stack(int v[]){
    int index = 0; //index of v
    int num = 1;   //to put to stack
    Stack *ps = CreateStack();
    Push(ps,0);    //dummy element
    while(index != N){  //pop t时,一定要先push 1,2,3…t-1,t,即要先将小于等于t的数都push入栈才能pop t。
        while(top(ps) < v[index] && index != N && (ps -> top + 1) <= M)  //这个过程中检查pop的次数是否等于N以及入栈的数目是否大于栈的容量M
            Push(ps,num++);
        if(top(ps) == v[index]){
            Pop(ps);
            index++;
        }else
            return 0;    //false
    }
    return 1;    //true
}

int main(){
    int i;
    scanf("%d%d%d",&M,&N,&K);
    int *v = (int *)calloc(N,sizeof(int));
    for (; K != 0; --K)
    {
        for( i = 0; i != N; ++i)
            scanf("%d", v+i);
        if (Check_Stack(v))
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值