Sequence(pascal)堆

来源:互联网 发布:手机淘宝v5.10.0 编辑:程序博客网 时间:2024/06/05 06:52

题意:

给n各组的数,每个组m个数,求出每个组去一个数的的和最小的m个数。

思路:

可以记录一个Δ为每个组的数对答案的影响,然后用堆维护Δ的最小值,然后会超时…..mdzz
这题想了我半天,本来想直接去网上看题解的,结果ymw大神说自己想(虽然他自己都想错了)。然后万般无奈就只能去百度搜索了。
正解:
1.将第一组数据输入arr1数组,升序排序。
2.将接下来的数据输入到arr2数组中,并且heap[i]=arr1[0]+arr2[0…n-1],
然后建一个堆
3.arr1数组从1到n-1,比较temp=arr1[i]+arr2[0…n-1]与堆顶的元素,如果temp比较小,则将堆顶元素pop,添加temp到heap;否则跳出循环。
4.将heap中的元素全部赋值给arr1数组,升序排序,重复2,3两步,直到所有数据全部处理完。

时间复杂度:

这题时间复杂度只看程序就是n次方logn。
但是在枚举每个数得时候最多就只会比较n次,然后就全部被break掉。所以就是(n*n*logn)

const maxn=2000; maxv=200;var data,data1,dataq:array [0..maxn] of longint; f:array [0..maxn,0..maxv] of longint; sum,k,t,i,j,n,m,p,ii:longint; q:array [0..maxv] of longint;procedure siftup(x:longint);var i,j:longint;begin i:=x; j:=x div 2; while j<>0 do begin  if dataq[i]>dataq[j] then  begin   dataq[0]:=dataq[i];   dataq[i]:=dataq[j];   dataq[j]:=dataq[0];  end else break;  i:=j;  j:=j div 2; end;end;procedure qsort(l,r:longint);var i,j,mid:longint;begin i:=l; j:=r; mid:=data[(l+r) div 2]; while i<j do begin  while data[i]<mid do inc(i);  while data[j]>mid do dec(j);  if i<=j then  begin   data[0]:=data[i];   data[i]:=data[j];   data[j]:=data[0];   inc(i); dec(j);  end; end; if i<r then qsort(i,r); if l<j then qsort(l,j);end;procedure siftdown(x:longint);var i,j:longint;begin i:=x; j:=x*2; while j<=m do begin  if (j+1<=m) and (dataq[j]<dataq[j+1]) then inc(j);  if dataq[j]>dataq[i] then  begin   dataq[0]:=dataq[i];   dataq[i]:=dataq[j];   dataq[j]:=dataq[0];  end else break;  i:=j;  j:=j*2; end;end;begin readln(t); for k:=1 to t do begin  fillchar(f,sizeof(f),$7f);  sum:=0;  readln(n,m);  for i:=1 to m do   read(data[i]);  readln;  for j:=1 to m-1 do    for ii:=j+1 to m do     if data[j]>data[ii] then     begin      data[0]:=data[j];      data[j]:=data[ii];      data[ii]:=data[0];     end;  for i:=1 to n-1 do  begin   for j:=1 to m do    read(data1[j]);   readln;   for j:=1 to m-1 do    for ii:=j+1 to m do     if data1[j]>data1[ii] then     begin      data1[0]:=data1[j];      data1[j]:=data1[ii];      data1[ii]:=data1[0];     end;   for j:=1 to m do   begin    dataq[j]:=data[j]+data1[1];    siftup(j);   end;   for j:=2 to m do    for ii:=1 to m do     if data1[j]+data[ii]<dataq[1] then     begin      dataq[1]:=data1[j]+data[ii];      siftdown(1);     end else break;   data:=dataq;   qsort(1,m);   fillchar(dataq,sizeof(dataq),0);  end;  for i:=1 to m do   write(data[i],' ');  writeln; end;end.
0 0
原创粉丝点击