Sequence(POJ--2442

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>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值