hdu 1280 top M

来源:互联网 发布:android 涂鸦板 源码 编辑:程序博客网 时间:2024/05/29 16:00

主题思想: 1,利用stl, priority_queue实现,利用数组自己进行堆实现,最小队列,实现topM算法。
事实证明自己利用数组实现,比利用priority_queue快。
堆用数组表示,下标从1开始,父节点为i那么两个son 下标分别是 2*i, 2*i+1
反过来孩子节点下标为k 父节点下标2*k

堆排序主要有两个操作,一个是swim ,一个是sink
当新插入一个元素时需要swim操作, 删除根节点时需要sink操作。

void exch(int i,int j){    int tmp=top[i];    top[i]=top[j];    top[j]=tmp;}//MinPQvoid swim(int k){    while(k>1&&top[k/2]>top[k]){        //        exch(k/2,k);        k/=2;    }}void sink(int k){    while(2*k<=n){        int j=2*k;        //j is the smaller between two son        if(j<n&&top[j]>top[j+1])j++;        //        if(top[k]<=top[j]) break;        exch(k,j);        k=j;    }}void delMin(){    exch(1,n--);    sink(1);    top[n+1]=0;}

AC代码:

#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;const int maxn=3005;int a[maxn];int top[maxn];int N,M;int n=0;void exch(int i,int j){    int tmp=top[i];    top[i]=top[j];    top[j]=tmp;}//MinPQvoid swim(int k){    while(k>1&&top[k/2]>top[k]){        //        exch(k/2,k);        k/=2;    }}void sink(int k){    while(2*k<=n){        int j=2*k;        //j is the smaller between two son        if(j<n&&top[j]>top[j+1])j++;        //        if(top[k]<=top[j]) break;        exch(k,j);        k=j;    }}void delMin(){    exch(1,n--);    sink(1);    top[n+1]=0;}void Insert(int x){    top[++n]=x;    swim(n);}int main(){    while(scanf("%d%d",&N,&M)!=EOF){        n=0;        memset(top,0,sizeof(maxn));        for(int i=0;i<N;i++){            scanf("%d",&a[i]);        }        for(int i=0;i<N-1;i++){            for(int j=i+1;j<N;j++){                Insert(a[i]+a[j]);                if(n>M) delMin();            }        }        //        sort(top+1,top+1+M);        printf("%d",top[M]);        for(int i=M-1;i>=1;i--){            printf(" %d",top[i]);        }        printf("\n");    }    return 0;}
原创粉丝点击