洛谷P1168 中位数

来源:互联网 发布:js修改div id 编辑:程序博客网 时间:2024/06/06 02:21

原题链接


特别水的题

对于前 1 个数中,中位数为它本身
可以建一个大根堆,储存的值都是小数
同样建一个小根堆,储存的值都是大数
在大根堆的堆顶放这K个数里的中位数
每次返回大根堆的堆顶

法一:STL
重点:
要保证大根堆减小根堆的个数不超过1
一次插入两个数,便于控制个数
注意:
要小心当n为偶数的情形,最后一个数字是没有用的,所以只处理前2*i-1个数字

//大根堆:priority_queue<int> Max;//小根堆:priority_queue<int, vector<int>, greater<int> > Min;#include<queue> using namespace std;int n,x;priority_queue<int> Max;priority_queue<int, vector<int>, greater<int> > Min;int main(){    scanf("%d%d",&n,&x);    Max.push(x);    printf("%d\n",Max.top());    for(int i=1;i<=((n-1)>>1);i++){//((n+1)>>1)-2        int pd=0;        for(int j=0;j<2;j++){            scanf("%d",&x);            if(x>Max.top()){                Min.push(x);                pd++;            }            else {                Max.push(x);                pd--;            }        }        if(pd<0){//两个数都在大根堆里             Min.push(Max.top());            Max.pop();        }        //=0 不管         else if(pd>0){            Max.push(Min.top());            Min.pop();        }    printf("%d\n",Max.top());    }    return 0;}#include<cstdio>#include<queue> using namespace std;int n,x;priority_queue<int> Max;priority_queue<int, vector<int>, greater<int> > Min;int main(){    scanf("%d%d",&n,&x);    Max.push(x);    printf("%d\n",Max.top());    for(int i=1;i<=((n-1)>>1);i++){//((n+1)>>1)-2        int pd=0;        for(int j=0;j<2;j++){            scanf("%d",&x);            if(x>Max.top()){                Min.push(x);                pd++;            }            else {                Max.push(x);                pd--;            }        }        if(pd<0){//两个数都在大根堆里             Min.push(Max.top());            Max.pop();        }        else if(pd>0){            Max.push(Min.top());            Min.pop();        }    printf("%d\n",Max.top());    }    return 0;}

法二:手写堆

#include<cstdio>#include<algorithm>#define maxn 200009using namespace std;int a[maxn], b[maxn], len = 0, len2 = 0;void add(int x){    a[++len] = x; int p = len;    while (p > 1 && a[p >> 1] > a[p]) {swap(a[p], a[p >> 1]);p >>= 1;}}int put(){    int x = a[1], p = 1, son; a[1] = a[len--];    while ((p << 1) <= len){        son = p << 1;        if (son < len && a[son + 1] < a[son]) ++son;        if (a[son] < a[p]) {            swap(a[p], a[son]);            p = son;        }        else p = len + 1;    }    return x;}void add2(int x){    b[++len2] = x; int p = len2;    while (p > 1 && b[p >> 1] < b[p]) {swap(b[p], b[p >> 1]);p >>= 1;}}int put2(){    int x = b[1], p = 1, son; b[1] = b[len2--];    while ((p << 1) <= len2){        son = p << 1;        if (son < len2 && b[son + 1] > b[son]) ++son;        if (b[son] > b[p]) {            swap(b[p], b[son]);            p = son;        }        else p = len2 + 1;    }    return x;}int main(){    int n, x1, x2, mid;    scanf("%d", &n);    scanf("%d", &x1);    add(x1); printf("%d\n", mid = x1);    for (int i = 1; i <= ((n-1)>>1); i++){        scanf("%d%d", &x1, &x2);        if (x1 < mid)add2(x1); else add(x1);        if (x2 < mid)add2(x2); else add(x2);        while (len2 >= len) add(put2());        while (len2 < len - 1) add2(put());        printf("%d\n", mid = a[1]);    }    return 0;}
0 0
原创粉丝点击