【PAT甲级】1057. Stack (30)

注:这里用left和right来记录median左右元素总个数(假设已按大小排序);结合set[median]即median元素的个数,来判断median是否需要向左右调整。

#include <stdio.h>
#include <stack>
#include <stdlib.h>
#include <string.h>
using namespace std;

void adjust();
void adjustleft();
void adjustright();

stack<int> s;
int set[100001] = {0};
int m = 0;
int left = 0;
int right = 0;

int main(int argc, char *argv[]) {
    char cmd[3][11] = {"Push", "Pop", "PeekMedian"};
    int n;
    scanf("%d", &n);
    int i, j;
    char in[20];
    for (i = 0; i < n; i++) {
        scanf("%s", in);
        if (strcmp(in, cmd[1]) == 0) {
            if (s.empty()) {
                printf("Invalid\n");
            } else {
                int tmp = s.top();
                printf("%d\n", tmp);
                s.pop();
                set[tmp]--;
                if (tmp < m) left--;
                else if (tmp > m) right--;
                adjust();
            }
        } else if (strcmp(in, cmd[0]) == 0) {
            int tmp;
            scanf("%d", &tmp);
            s.push(tmp);
            set[tmp]++;
            if (tmp < m) left++;
            else if (tmp > m) right++;
            adjust();
        } else if (strcmp(in, cmd[2]) == 0) {
            if (m != 0)
                printf("%d\n", m);
            else
                printf("Invalid\n");
        }
    }

    return 0;
}

void adjust() {
    if (left + set[m] < right) {
        adjustright();
    } else if (left >= set[m] + right) {
        adjustleft();
    } else if (s.empty()) {
        m = left = right = 0;
    }
}
void adjustleft() {
    right += set[m];
    int t;
    for (t = m - 1; set[t] == 0; t--);  
    m = t;
    left -= set[m];
}
void adjustright() {
    left += set[m];
    int t;
    for (t = m + 1; set[t] == 0; t++);  
    m = t;
    right -= set[m];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值