序列合并(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.  

 

你可能感兴趣的:(序列)