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 4
 1 /*

 2 解题步骤:

 3 1,输入第一个序列并进行升序排序

 4 2,输入一个序列进行升序排序,并将num1[0]+num2[i](0<=i<=n-1)结果放入优先队列

 5    que中,然后num1[1]+num2[i](0<=i<=n-1),若num1[1]+num2[i](0<=i<=n-1)>que.top()

 6    就删除que的队首并将num1[1]+num2[i](0<=i<=n-1)进队列,然后是num1[2]+num2[i](0<=i<=n-1)...

 7 3, 将que中的元素拷贝到num1[]中,注意是升序排列

 8 4,循环2,3直到所有数据读入完毕

 9 5,打印num1[]中数据

10 */

11 #include<stdio.h>

12 #include<stdlib.h>

13 #include<algorithm>

14 #include<queue>

15 #include<iostream>

16 using namespace std;

17 

18 int num1[2001],num2[2001];

19 int main()

20 {

21     int t,n,m;

22     scanf("%d",&t);

23     while(t--)

24     {

25         priority_queue< int, deque<int>, less<int> >que;

26         while(!que.empty())

27             que.pop();

28         scanf("%d %d",&m,&n);

29         for(int j = 0; j < n; j++)

30             scanf("%d",&num1[j]);

31         sort(num1,num1+n);

32 

33         for(int i = 1; i < m; i++)//再输入m-1个序列,也相当于进行m-1次两个序列的归并

34         {

35             for(int j = 0; j < n; j++)

36             {

37                 scanf("%d",&num2[j]);

38                 que.push(num2[j] + num1[0]);

39             }

40             sort(num2,num2+n);

41             for(int k = 1; k < n; k++)

42                 for(int l = 0; l < n; l++)

43                 {

44                     if(num1[k] + num2[l] > que.top())

45                         break;

46 

47                     que.pop();

48                     que.push(num1[k]+num2[l]);

49 

50                 }

51             for(int j = 0; j < n; j++)

52             {

53                 num1[n-1-j] = que.top();

54                 que.pop();

55             }

56         }

57         printf("%d",num1[0]);

58         for(int j = 1; j < n; j++)

59             printf(" %d",num1[j]);

60         printf("\n");

61     }

62     return 0;

63 }
View Code

priority_queue:优先队列

顾名思义,这个东西可以用于存放单调的数据,后面将会看到用于优化Dijkstra

有3个类函数:

void push(元素类型   变量)

void pop()

int top()

int size()

bool empty()

分别是:

  • 加入类型是XXX的变量XXX
  • 弹出队列首元素
  • 取优先队列的队首元素的值
  • 返回队列元素数量
  • 查看队列是否为空

定义:

  1. priority_queue <数据类型容器类型元素比较方式>
  2. priority_queue <数据类型容器类型>
  3. priority_queue <数据类型>

数据类型:int,double.....

容器类型:vector(默认),deque,但不能是list

元素比较方式:less(默认,不上升序),greater(不下降序);

 

优先队列的第一种用法,也是最常用的用法:

 

priority_queue< int> qi;

 

通过<操作符可知在整数中元素大的优先级高。
故示例1中输出结果为:9 6 5 3 2

第二种方法:
在示例1中,如果我们要把元素从小到大输出怎么办呢?
这时我们可以传入一个比较函数,使用functional.h函数对象作为比较函数。

 

priority_queue< int, vector< int>, greater< int> >qi2;

 

其中
第二个参数为容器类型。
第二个参数为比较函数。
故示例2中输出结果为:2 3 5 6 9

第三种方法:
自定义优先级。

 

struct node
{
    friend bool operator< (node n1, node n2)
    {
        return n1.priority < n2.priority;
    }
    int priority;
    int value;
};

 

在该结构中,value为值,priority为优先级。
通过自定义operator<操作符来比较元素中的优先级。
在示例3中输出结果为:
优先级  值
9          5
8          2
6          1
2          3
1          4
但如果结构定义如下:

 

struct node
{
     friend bool operator> (node n1, node n2)
    {
         return n1.priority > n2.priority;
    }
     int priority;
     int value;
};

则会编译不过(G++编译器)
因为标准库默认使用元素类型的<操作符来确定它们之间的优先级关系。
而且自定义类型的<操作符与>操作符并无直接联系,故会编译不过。

补充的一点是:

我们可以自己写一个比较类,还设定优先级:

struct cmp
{
    bool operator() (const int &a, const int &b)
    {
        return dist[a] > dist[b];
    }
};

priority_queue<int,vector<int>,cmp> q;(按照元素的dist大小从小到大排序).

 

你可能感兴趣的:(sequence)