您的位置:首页 > 产品设计 > UI/UE

POJ 2442 Sequence(堆的应用)

2012-04-10 21:13 615 查看
Sequence

Time Limit: 6000MS

Memory Limit: 65536K

Total Submissions: 4906

Accepted: 1490

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

Source

POJ Monthly,Guang Lin

解题报告:这道题的题意是给我们m, n,下面有m行,每行有n个数,让我们求出前n个最小组合的和,共有n ^ m种的组合,但是只是让我们求出前n组即可,思路就是利用堆的性质,在遍历求和的同时调整堆;用的是STL写的

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX = 2010;
int a[MAX], b[MAX], heap[MAX];
int main()
{
int i, j, m, n, t, flag;
scanf("%d", &t);
while (t --)
{
scanf("%d%d", &m, &n);
for (i = 0; i < n; ++i)
{
scanf("%d", &a[i]);
}
sort(a, a + n);//将数组a按从小到大排序
while (-- m)
{
for (i = 0; i < n; ++i)
{
scanf("%d", &b[i]);
}
sort(b, b + n);//将数组b按从小到大排序
for (i = 0; i < n; ++i)
{
heap[i] = a[i] + b[0];
}
make_heap(heap, heap + n);//make_heap 是按照给定的排序准则,把“最大”的元素排列到首位,而其他元素看上去并非有序:
//相当于建立大顶堆
// 例如:输入 5个数 2 4 6 5 3 经历操作是 6 5 4 2 3
for (i = 1; i < n; ++i)
{
flag = 0;
for (j = 0; j < n; ++j)
{
int temp = b[i] + a[j];
if (temp < heap[0])
{
//pop_heap()不是真的把最大(最小)的元素从堆中弹出来。而是重新排序堆
//它把0和i个元素交换,然后将[0,i)的数据再做成一个大顶堆堆。
pop_heap(heap, heap + n);
heap[n - 1] = temp;
//push_heap()假设由[0,i)是一个有效的堆,
//然后,再把堆中的新元素加进来,做成一个堆。
push_heap(heap, heap + n);
flag = 1;
}
else
{
break;//当前已经是最小了
}
}
if (flag == 0)
{
break;//已经求出前n个最小的组合的和了
}
}
for (i = 0; i< n; ++i)
{
a[i] = heap[i];
}
sort(a, a + n);//重新排序
}
for (i = 0; i < n - 1; ++i)
{
printf("%d ", a[i]);
}
printf("%d\n", a[n - 1]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: