题意:
给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.