题意是比较容易理解的,直接枚举的话会有k的k次方,肯定超时,开始我想每次取最小的n个值,与接下来的n个数的分别相加,这样复杂度大概是n的3次方,然后TLE。。。。
翻阅了下白书,书中将两行之间相加的过程进一步化简,先从小到大排序,分别取第一行的n个数,与第二行的第一个数相加,进入优先队列(小的在前),取队列中第一个值,
并进队后面一个数(具体理解见代码),这样取出n个数,即使这两行合并的最小的n个数,然后与后面的数列逐一合并,最后得出结果
#include <iostream>
#include <cstring>
#include <vector>
#include <stdio.h>
#include <queue>
#include <algorithm>
using namespace std;
struct note
{
int sum,pos;
bool operator < (const note &rhs) const
{
return sum>rhs.sum;
}
note(int a,int b):sum(a),pos(b){};
};
int merge(int* a,int* b,int* c,int n)
{
priority_queue<note>q;
for(int i=0;i<n;i++)
{
q.push(note(a[i]+b[0],0));
}
for(int i=0;i<n;i++)
{
note tmp=q.top();
q.pop();
c[i]=tmp.sum;
if(tmp.pos+1<n)
q.push(note(tmp.sum-b[tmp.pos]+b[tmp.pos+1],tmp.pos+1));
}
return 1;
}
int a[800];
int b[800];
int main()
{
//freopen("in.txt","r",stdin);
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,a+n);
//printf("ss");
for(int h=1;h<n;h++)
{
for(int i=0;i<n;i++)
{
scanf("%d",&b[i]);
}
sort(b,b+n);
merge(a,b,a,n);
}
printf("%d",a[0]);
for(int i=1;i<n;i++)
printf(" %d",a[i]);
printf("\n");
}
}