题意:有m组数,每组n个。从每组中取一个数求和,可以得到n^m个和,求这n^m个数中的最小的n个
思路:一组一组数据的处理,建立大顶堆。heap为大顶堆,s数组保存每组数的读入,temp是处理到当前组的前n小的数的递增序列。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 2002
int heap[N],s[N],temp[N];
int T,n,m;
int cmp(const int *a,const int *b){
return (*a)-(*b);
}
void adjust(int i){
int temp = heap[i];
i <<= 1;
while(i<=n){
if(i+1<=n && heap[i+1]>heap[i])
i++;
if(temp > heap[i])
break;
heap[i/2] = heap[i];
i <<= 1;
}
heap[i/2] = temp;
}
int main(){
freopen("a.txt","r",stdin);
scanf("%d",&T);
while(T--){
int i,j,loop ;
scanf("%d %d",&m,&n);
loop = m-1;
for(i = 1;i<=n;i++){
scanf("%d",&s[i]);
heap[i] = s[i];
temp[i] = s[i];
}
for(i = n/2;i>=1;i--)//建立大顶堆
adjust(i);
qsort(temp+1,n,sizeof(int),cmp);
while(loop--){
for(i = 1;i<=n;i++)
scanf("%d",&s[i]);
qsort(s+1,n,sizeof(int),cmp);
for(i = 1;i<=n;i++)
heap[i] += s[1];
for(i = 2;i<=n;i++){
for(j = 1;j<=n;j++){
if(s[i] + temp[j] < heap[1]){
heap[1] = s[i]+temp[j];
adjust(1);
}else
break;
}
if(j==1)
break;
}
for(i = 1;i<=n;i++)
temp[i] = heap[i];
qsort(temp+1,n,sizeof(int),cmp);
}
for(i = 1;i<=n;i++)
printf("%d ",temp[i]);
printf("\n");
}
return 0;
}