• 堆——练习题


    ……堆是一个很好用的东西,但遗憾的是,在oi混了三年多的我居然到现在才会……惭愧惭愧……

    堆可以在O(log n) 的时间内查询最大值和最小值,非常好用的一个数据结构,本人认为比优先队列快得多……只是本人观点……

    手写堆:不好写……没写过……反正c++有stl库(等到了左偏树再学……)

    stl堆:感谢c++有stl这种省时省力的好东西,要是noip开放所有库并允许o2 o3优化就更好了(退役之前不用想了)

    stl堆函数:

    make_heap:将一个数组建堆,例:对a[1]到a[100]建堆:make_heap(a+1,a+1+100)(可添加comp)

    pop_heap:将堆顶元素弹出,弹到……一般是堆底,例:将上边的堆堆顶弹到堆底:pop_heap(a+1,a+1+n)(可添加comp)

    push_heap:将堆底(一般是)元素弹到堆顶,例:把上面的再弹回来:push_heap(a+1,a+1+n)(可添加comp)

    sort_heap:堆排序,其实很少用,我没用过……好像用一下就不是一个正常的堆了……,例:sort_heap(a+1,a+1+n)(可添加comp)

    comp函数的注意事项:

    ……就一个:如果是要建大根堆,就return a<b;建小根堆return a>b;其实默认是大根堆……

    例题1:

    合并果子:

    题意:百度上有…………………………………………………………………………我好不负责任……

    思路:看完题意就会了……………………………………………………………………

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<queue>
     7 #include<algorithm>
     8 #include<vector>
     9 #include<map>
    10 #include<set>
    11 using namespace std;
    12 int n,ans=0,a[10024]={0};
    13 bool cmp(int e,int t){
    14     if(e<t) return false;
    15     return true;
    16 }
    17 int main(){
    18 //    freopen("goods.in","r",stdin);
    19 //    freopen("goods.out","w",stdout);
    20     scanf("%d",&n);
    21     for(int i=0;i<n;i++) scanf("%d",&a[i]);
    22     make_heap(a,a+n,cmp);
    23     for(int i=n;i>1;i--){
    24          pop_heap(a,a+i,cmp);
    25          pop_heap(a,a+i-1,cmp);
    26          a[i-2]=a[i-2]+a[i-1];
    27          ans=ans+a[i-2];
    28          push_heap(a,a+i-1,cmp);
    29     }
    30     cout<<ans<<endl;
    31 //    fclose(stdin);
    32 //    fclose(stdout);
    33     return 0;
    34 }

     例2:

    序列合并

    题意:给两个序列a,b, 两个序列中的数非递减,两个序列长度都为n,求最小的n个(a[i]+b[j]),不可重复。

    数据范围:n:1---100000;

    输入格式:

              n

              a[1] a[2] a[3]……a[n]

              b[1] b[2] b[3]……b[n]

    输出格式:

              n个数,用空格隔开……

    样例:

    输入:3

              2 6 6

              1 4 8

    输出:3 6 7

    思路:

    因为 a[1]+b[i]<=a[2]+b[i]<=a[3]+b[i]……

    所以先将 a[1]+b[1],a[1]+b[2],a[1]+b[3]……a[1]+b[n]存入堆,进行n次操作,每次操作:

    1.取出堆中最小值,放入答案

    2.用下一个数取代这个最小值,放入堆(如:如果堆最小值为a[1]+b[1],那么就放入a[2]+b[1];如果堆最小值为a[42]+b[323],那么就放入a[43]+b[323])

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<string>
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<iostream>
     7 using namespace std;
     8 
     9 
    10 int a[200000],b[200000],n;
    11 int ans[200000],m;
    12 struct ad{
    13     int sum;
    14     int xv;
    15     int hao;
    16 }c[200000];
    17 
    18 bool cmp(const ad a,const ad b){
    19     return a.sum>b.sum;
    20 }
    21 
    22 int main(){
    23     scanf("%d ",&n);
    24     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    25     for(int i=1;i<=n;i++) scanf("%d",&b[i]);
    26     for(int i=1;i<=n;i++) c[i].sum=a[1]+b[i];
    27     for(int i=1;i<=n;i++) c[i].hao=i;
    28     for(int i=1;i<=n;i++) c[i].xv=1;
    29     make_heap(c+1,c+1+n,cmp);
    30     while(m<n){
    31         pop_heap(c+1,c+1+n,cmp);
    32         m++;
    33         ans[m]=c[n].sum;
    34         c[n].xv++;
    35         c[n].sum=a[c[n].xv]+b[c[n].hao];
    36         push_heap(c+1,c+1+n,cmp);
    37     }
    38     for(int i=1;i<=n;i++) printf("%d ",ans[i]);
    39     return 0;
    40 }
  • 相关阅读:
    PHP之十六个魔术方法详解
    PHP之十六个魔术方法详解
    让Docker容器使用静态独立的外部IP(便于集群组建)
    桥接和nat模式区别
    使用 GitHub / GitLab 的 Webhooks 进行网站自动化部署
    docker gitlab
    docker gitlab安装
    docker ui管理工具
    docker 批量删除容器
    Scrapy设置代理
  • 原文地址:https://www.cnblogs.com/Misaki-Mei/p/7499127.html
Copyright © 2020-2023  润新知