• 序列合并(luogu 1631)题解


    【问题描述】

    有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N^2个和,求这N^2个和中最小的N个。

    【样例输入】

        3
        2 6 6
        1 4 8

    【样例输出】

        3 6 7

    【解题思路】

         这道题目其实是一道裸的最小堆的题目,而且它给出了Ai<=A(i+1),Bi<=B(i+1),我们连排序都可以不用排,我们建一个堆为C,首先C中存放N个值,分别为A1+B1,A2+B1,...An+B1,然后我们将其建成一个小根堆,每一次取堆顶元素并维护,然后插入Ai+B(j+1)到堆中并维护,因此,我们需要一个记录类型来作为堆,该记录类型有着三个值,分别存储i,j和a[i]+b[j]的值,然后我们以a[i]+b[j]为关键字维护堆即可。

    【代码实现】

      1 type rec=record  
      2      jbh,data,ibh:longint;  
      3 end;  
      4 var n,i,j,n1,ii,jj:longint;  
      5     a,b:array[0..100010] of longint;  
      6     c:array[0..100010] of rec;  
      7 procedure sift(i,m:longint);  
      8 var k:longint;  
      9 begin  
     10  c[0]:=c[i];  
     11  k:=i shl 1;  
     12  while k<=m do  
     13   begin  
     14    if (k<m)and(c[k].data<c[k+1].data) then  
     15     inc(k);  
     16    if c[0].data<c[k].data then  
     17     begin  
     18      c[i]:=c[k];  
     19      i:=k;  
     20      k:=i shl 1;  
     21     end  
     22    else  
     23     k:=m+1;  
     24   end;  
     25  c[i]:=c[0];  
     26 end;  
     27 procedure insert(k,ii,jj:longint);  
     28 var i:longint;  
     29     y:rec;  
     30 begin  
     31  inc(n1);  
     32  c[n1].data:=k;  
     33  c[n1].ibh:=ii;  
     34  c[n1].jbh:=jj;  
     35  i:=n1;  
     36  while (i shr 1>0)and(c[i shr 1].data>k) do  
     37   begin  
     38    y:=c[i];  
     39    c[i]:=c[i shr 1];  
     40    c[i shr 1]:=y;  
     41    i:=i shr 1;  
     42   end;  
     43 end;  
     44 procedure heapsort;  
     45 var j:longint;  
     46     y:rec;  
     47 begin  
     48  for j:=n shr 1 downto 1 do  
     49   sift(j,n);  
     50  for j:=n downto 2 do  
     51   begin  
     52    y:=c[1];  
     53    c[1]:=c[j];  
     54    c[j]:=y;  
     55    sift(1,j-1);  
     56   end;  
     57 end;  
     58 function deletemin:longint;  
     59 var i,pos:longint;  
     60     y:rec;  
     61 begin  
     62  i:=1;  
     63  deletemin:=c[1].data;  
     64  c[1]:=c[n1];  
     65  dec(n1);  
     66  while i shl 1<=n1 do  
     67   begin  
     68    pos:=i shl 1;  
     69    if (pos<n1)and(c[pos+1].data<c[pos].data) then  
     70     inc(pos);  
     71    if c[i].data>c[pos].data then  
     72     begin  
     73      y:=c[i];  
     74      c[i]:=c[pos];  
     75      c[pos]:=y;  
     76      i:=pos;  
     77     end  
     78    else  
     79     break;  
     80   end;  
     81 end;  
     82 begin  
     83  readln(n);  
     84  for i:=1 to n do  
     85   read(a[i]);  
     86  for i:=1 to n do  
     87   read(b[i]);  
     88  for i:=1 to n do  
     89   begin  
     90    c[i].data:=a[i]+b[1];  
     91    c[i].jbh:=1;  
     92    c[i].ibh:=i;  
     93   end;  
     94  heapsort;  
     95  n1:=n;  
     96  for i:=1 to n do  
     97   begin  
     98    ii:=c[1].ibh;  
     99    jj:=c[1].jbh;  
    100    write(deletemin,' ');  
    101    inc(jj);  
    102    insert(a[ii]+b[jj],ii,jj);  
    103   end;  
    104 end.  
  • 相关阅读:
    PHP实现发送模板消息(微信公众号版)
    laravel 跨域问题
    微信授权登录
    支付demo2
    支付demo1
    微信支付注意点
    微信支付方式区分
    debian,dietpi,linux中文乱码解决方法
    嵌入式应该深入专研STM32还是继续学习linux内核驱动呢?
    arduino下载ESP8266开发板的方法
  • 原文地址:https://www.cnblogs.com/PengBoLiuXu/p/4553766.html
Copyright © 2020-2023  润新知