美文网首页
PAT 甲级 刷题日记|A 1057 Stack (30 分)

PAT 甲级 刷题日记|A 1057 Stack (30 分)

作者: 九除以三还是三哦 | 来源:发表于2021-08-14 10:36 被阅读0次

    题目

    Stack is one of the most fundamental data structures, which is based on the principle of Last In First Out (LIFO). The basic operations include Push (inserting an element onto the top position) and Pop (deleting the top element). Now you are supposed to implement a stack with an extra operation: PeekMedian -- return the median value of all the elements in the stack. With N elements, the median value is defined to be the (N/2)-th smallest element if N is even, or ((N+1)/2)-th if N is odd.

    Input Specification:

    Each input file contains one test case. For each case, the first line contains a positive integer N (≤105). Then N lines follow, each contains a command in one of the following 3 formats:

    Push key
    Pop
    PeekMedian
    

    where key is a positive integer no more than 105.

    Output Specification:

    For each Push command, insert key into the stack and output nothing. For each Pop or PeekMedian command, print in a line the corresponding returned value. If the command is invalid, print Invalid instead.

    Sample Input:

    17
    Pop
    PeekMedian
    Push 3
    PeekMedian
    Push 2
    PeekMedian
    Push 1
    PeekMedian
    Pop
    Pop
    Push 5
    Push 4
    PeekMedian
    Pop
    Pop
    Pop
    Pop
    结尾无空行
    

    Sample Output:

    Invalid
    Invalid
    3
    2
    2
    1
    2
    4
    4
    5
    3
    Invalid
    结尾无空行
    

    思路

    这个题目关键在于实现 PeekMedian 的操作,即找到一堆数的中位数。开始用sort,结果超时,实际上应该使用树形数组。

    树形数组和之前学过的二叉树之类的关系不大。形式如下图所示,适宜单点更新、区间查询等操作。感觉考点并不常见,先战术放弃,后续有时间再更新。


    1628827049784.png

    代码

    #include <iostream>
    #include <stack>
    #define lowbit(i) ((i) & (-i))
    const int maxn = 100010;
    using namespace std;
    int c[maxn];
    stack<int> s;
    
    void update(int x, int v) {
        for(int i = x; i < maxn; i += lowbit(i))
            c[i] += v;
    }
    
    int getsum(int x) {
        int sum = 0;
        for(int i = x; i >= 1; i -= lowbit(i))
            sum += c[i];
        return sum;
    }
    
    void PeekMedian() {
        int left = 1, right = maxn, mid, k = (s.size() + 1) / 2;
        while(left < right) {
            mid = (left + right) / 2;
            if(getsum(mid) >= k)
                right = mid;
            else
                left = mid + 1;
        }
        printf("%d\n", left);
    }
    
    int main() {
        int n, temp;
        scanf("%d", &n);
        char str[15];
        for(int i = 0; i < n; i++) {
            scanf("%s", str);
            if(str[1] == 'u') {
                scanf("%d", &temp);
                s.push(temp);
                update(temp, 1);
            } else if(str[1] == 'o') {
                if(!s.empty()) {
                    update(s.top(), -1);
                    printf("%d\n", s.top());
                    s.pop();
                } else {
                    printf("Invalid\n");
                }
            } else {
                if(!s.empty())
                    PeekMedian();
                else
                    printf("Invalid\n");
            }
        }
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:PAT 甲级 刷题日记|A 1057 Stack (30 分)

          本文链接:https://www.haomeiwen.com/subject/sdmdbltx.html