C/C++教程

c++pat1057(分块)

本文主要是介绍c++pat1057(分块),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

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.

栈是一种基础的数据结构,它基于后进先出的数据结构,基础的操作,包括push和pop,现在要求你操作一个栈,有额外的操作,输出栈的中位数。返回栈的中位数。假如有N个元素,N/2是中位数,最小的是偶数,如果N是奇数,(N+1)/2是奇数。

Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤10 5 ). 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 10 5

输入规格:每个输入文件包含一个测试案例,针对每个测试案例,第一行包含一个正整数 N,然后N行包含这样的三个操作。Push key Pop PeekMedian,key是一个不会超过1e5的整数

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.

输出规格: 针对每个push命令,插入key元素到栈中,什么都不输出,针对每个Pop或者peek米宁陵1,打印相应返回去数据,如果命令无效,打印无效代替。

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

核心思路

分块思想来做,也不简单,栈空如果还操作记得返回invalid

完整源码

#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
const int maxn = 100010;
const int sqrN = 316;

stack<int> st;
int block[sqrN];//记录每一块中存在的元素个数
int table[maxn];//hash数组,记录元素当前存在个数

void peekMedian(int K){
    int sum = 0;
    int idx = 0;
    while(sum + block[idx] < K){
        sum += block[idx++];
    }
    int num = idx * sqrN;
    while(sum + table[num] < K){
        sum += table[num++];
    }
    printf("%d\n",num);
}

void Push(int x){
    st.push(x);
    block[x/sqrN]++;//x所在的块的元素个数加1
    table[x]++; //x的存在个数加1
}

void Pop(){
    int x = st.top();
    st.pop();
    block[x/sqrN]--;
    table[x]--;
    printf("%d\n",x);
}

int main(){
    int x,query;
    memset(block,0,sizeof(block));
    memset(table,0,sizeof(table));
    char cmd[20];
    scanf("%d",&query);
    for(int i =0;i<query;i++){
        scanf("%s",cmd);
        if(strcmp(cmd,"Push")==0){
            scanf("%d",&x);
            Push(x);
        }else if(strcmp(cmd,"Pop") == 0){
            if(st.empty() == true){
                printf("Invalid\n");
            }else{
                Pop(); //出栈
            }
        }else{
            if(st.empty() == true){
                printf("Invalid\n");
            }else{
                int K = st.size();
                if(K%2==1) K = (K+1)/2;
                else K = K /2;
                peekMedian(K);
            }
        }
    }
    return 0;
}
这篇关于c++pat1057(分块)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!