演算法題 - Pop Sequence

云茗發表於2024-03-11

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的堆疊,按照1~N(M可能小於N)的順序往其中填入數字, 可以在任意時刻pop出一個數字。現在給定一個序列, 問這個序列是不是一個可能的出棧序列。

處理思路:

  1. 因為堆疊長度與數字數量不同,因此需要保證當前棧內的元素數量不超過M個。
  2. 因為在一個元素出棧時,在這個元素之前的所有元素(比它小的那些數字),必定已經出棧或在棧內;如果在棧內,則這些元素必然按照後到前的順序排列(它後面未出棧的,比它小的數字,必然按照大到小的順序排列)。
  3. 當前棧的元素數量 = 比某個數小的所有未出棧的數。
  4. 輸入部分,先開3個變數存放,然後開一個二維陣列存放;輸出部分,開一個01表示的結果陣列,最後用3元表示式輸出。

實現程式碼:

點選檢視程式碼
#include <stdio.h>

void Solution(int maxCapacity, int length, int seqNum);

int main()
{
    int maxCapacity, length, seqNum;
    scanf("%d%d%d", &maxCapacity, &length, &seqNum);
    Solution(maxCapacity, length, seqNum);
}

void Solution(int maxCapacity, int length, int seqNum)
{
    int sequcences[seqNum][length];

    for (int i = 0; i < seqNum; i++)
    {
        for (int j = 0; j < length; j++)
        {
            scanf("%d", &sequcences[i][j]);
        }
    }

    int res[seqNum] = {0};
    for (int i = 0; i < seqNum; i++)
    {
        // 掃描這行的每個數
        for (int j = 0; j < length; j++)
        {
            int temp = sequcences[i][j];
            int count = 1;
            // 每個數後比他小的數必須遞減排列
            for (int k = j; k < length; k++)
            {
                if (sequcences[i][k] >= sequcences[i][j])
                {
                }
                else if (sequcences[i][k] < temp)
                {
                    count++;
                    temp = sequcences[i][k];
                }
                else
                {
                    res[i] = 1;
                }
            }

            if (count > maxCapacity)
            {
                res[i] = 1;
            }
            if (res[i] != 0)
            {
                break;
            }
        }
    }

    for (int i = 0; i < seqNum - 1; i++)
    {
        printf("%s\n", res[i] == 0 ? "YES" : "NO");
    }

    printf("%s", res[seqNum - 1] == 0 ? "YES" : "NO");
}

寫在後面的一些小牢騷

其實一開始就是用這種方法做的,但一直不對,卻又搞不清楚是哪裡出了問題。於是先想要換別的方法做,後面看到其他人也用類似的方法做過,於是決定繼續研究,檢查了半天才發現是輸出結果的最後一行程式碼指標少寫了一個"-1"。
不過這種方法可能不太好,時間複雜度高了一級(多掃描了一輪),還額外佔用了不少空間(用一個二維陣列,還有一個結果陣列,網上其他的方法似乎都挺簡單)。

相關文章