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.
题意:总共多组数据,每组数据有m行,每行有n个数,每次从m行里边每行抽出一个数相加构成n个数,求最小的n个数。
思路:先输入第一个数组,然后从第二个数组开始往队列里存n个数,只要碰到比优先队列里的最大元素小的数就更新优先队列。
Sample Input
1 2 3 1 2 3 2 2 3
Sample Output
3 3 4
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
int a[20000],b[20000];
int main()
{
// freopen("../oo.text","r",stdin);
int t,m,n,i,j,k;
scanf("%d",&t);
priority_queue<int>q; //优先队列默认的排序是升序即队顶是最大的数
while(t--)
{
scanf("%d %d",&m,&n);
for(i=0; i<n; i++)
scanf("%d",&a[i]); //先输入第一个数组
sort(a,a+n); //对第一个数组按升序排序
for(i=1; i<m; i++)
{
for(j=0; j<n; j++) <span style="font-family: Arial, Helvetica, sans-serif;">//接着输入后边的数组并排序</span>
scanf("%d",&b[j]);
sort(b,b+n);
for(j=0; j<n; j++)
{
q.push(a[j]+b[0]); //先将第一个数组的数与b[0]相加后放入队列里
}
for(j=1; j<n; j++) //将第一个数组的数与b[1]之后的每个数相加与队列里的数进行比较
for(k=0; k<n; k++)
{
int x=q.top();
if((a[k]+b[j])>=x) //如果相加比队顶元素大就直接跳出,因为数组是排序之后的,当前相加已经比队顶元素大了那么之后的和肯定也会比队顶元素大
break;
q.pop(); //如果和比队顶元素小就更新优先队列
q.push(a[k]+b[j]);
}
for(j=n-1; j>=0; j--) //将更新后的优先队列放到第一个数组里以便与后边的数组相加得出最小累加和
{
a[j]=q.top();
q.pop();
}
}
for(i=0; i<n; i++)
printf("%d%c",a[i],i==n-1?'\n':' ');
}
return 0;
}<strong>
</strong>