【堆】poj2442
Sequence
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
题目大意:输入m个集合,每个含n个数,求从每个集合取一个数后,按非降序输出前n小的和。
这个题是看了网上的题解才知道怎么做的
1:向A读入一个集合
2:向B读入下一个集合,用它最小的数遇上一个集合的每一个数相加,加入大根堆中,取出它的第二小的值与第一个集合中的值分别相加,如果该值小于大根堆堆顶的值,删除堆顶,将当前值加入,然后依此类推。
3:将堆中元素依次取出,逆向放入A中
4:重复2,3
//表达能力比较差……说得乱七八糟……
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
priority_queue <long> q;
long a[2020], b[2020];
long t, n, m;
void init()
{
}
int main()
{
freopen("poj2442.in", "r", stdin);
scanf("%d",&t);
for (long i = 1; i <= t; i++)
{
memset(a, sizeof(a), 0);
scanf("%d%d", &n, &m);
for (long i = 0; i < m; i++)
{
scanf("%d", &a[i]);
}
sort(a, a + m);
for (long i = 2; i <= n; i++)
{
for (long j = 0; j <m; j++)
scanf("%d", &b[j]);
sort(b, b + m);
for (long j = 0; j < m; j++)
q.push(a[0]+b[j]);
for (long j = 1; j < m; j++ )
for (long k = 0; k < m; k++)
{
if (a[j] + b[k] < q.top())
{
q.pop();
q.push(a[j] + b[k]);
}
}
for (long j = m - 1; j >= 0; j--)
{
a[j] = q.top();
q.pop();
}
}
for (long j = 0 ; j < m; j++ )
printf ("%d ",a[j]);
cout<<endl;
}
return 0;
}