题意;m * n 的矩阵 m行n列,每一行取一个数加起来,形成一个排列,升序输出排列和最小的前n个。
解题思路:维护两个数组,和一个优先队列,两个数组滚动使用。先对输入进来的每一行进行排序(升序)。把相邻的两行的值的和压入队列,在这个过程中队列中只保留n个元素,即比较小的n个, 多出n个就, 弹出最大的。
具体步骤如下:
1,读入第一行a[i],把第一行进行排序,再读入第二行b[i],用第一行的最小值a[0]与第二行的每个数相加,压入队列。
2,循环a[1]...a[n]与b[0]...b[n]的和与队列中的最大值进行比较,如果和值小于最大值就弹出最大值,压入和值,如果大于等于就break(因为是b[i]排过序的,这里和值如果大于等于,后面的和值也只能是大于等于)
3,按升序更新a[i],a[i]就是队列中的值, 反复第2步,直到结束.
Description
Given m sequences, each contains n non-negative integer. Now we may select one number from each sequence to form a sequence with m integers. It's clear that we may get n ^ m this kind of sequences. Then we can calculate the sum of numbers in each sequence, and get n ^ m values. What we need is the smallest n sums. Could you help us?
Input
The first line is an integer T, which shows the number of test cases, and then T test cases follow. The first line of each case contains two integers m, n (0 < m <= 100, 0 < n <= 2000). The following m lines indicate the m sequence respectively. No integer in the sequence is greater than 10000.
Output
For each test case, print a line with the smallest n sums in increasing order, which is separated by a space.
Sample Input
1 2 3 1 2 3 2 2 3
Sample Output
3 3 4
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<list>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define MAX_N 2005
using namespace std;
int n, m;
int a[MAX_N];
int b[MAX_N];
priority_queue<int> pq;
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &m, &n);
for(int i = 0 ; i < n; i++)
scanf("%d", &a[i]);
sort(a, a + n);
while(--m)
{
for(int i = 0 ; i < n ; i++)
{
scanf("%d", &b[i]);
pq.push(a[0] + b[i]);
}
sort(b, b + n);
for(int i = 1 ; i < n ; i++)
{
for(int j = 0 ; j < n ; j++)
{
if(a[i] + b[j] >= pq.top())
break;
pq.pop();
pq.push(a[i] + b[j]);
}
}
for(int i = n -1 ; i >= 0 ; i--)
{
a[i] = pq.top();
pq.pop();
}
}
for(int i = 0 ; i < n - 1 ; i++)
{
printf("%d ", a[i]);
}
printf("%d\n", a[n -1]);
}
return 0;
}