序列合并(luogu 1631)题解

来源:互联网 发布:知乎 国家开发投资集团 编辑:程序博客网 时间:2024/05/18 05:13
【问题描述】

有两个长度都是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.  

 

0 0
原创粉丝点击