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; }