Zznu 1913: yifan and matrix (多路归并)

题目链接:

  1913: yifan and matrix

题目描述:

  有一个n*n的矩阵,在每一行取出一个数,可以得到n个数的和,问前n小的和分别是多少?

解题思路:
  对于两个数组a[n],b[n],我们可以用二路归并维护一个升序序列a[i]+b[j](1<=i<=n,1<=j<=n),先把a[i]+b[1](1<=i<=n)加进优先队列,每次取出队首元素,记录下来,然后再改变为a[i]+b[j+1]再加进队列.

依次进行n-1二路合并即可。

  优美的代码将要闪亮登场!!!!!

 1 #include <queue>
 2 #include <cstdio>
 3 #include <string>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;
 7 const int maxn = 500;
 8 struct node
 9 {
10     int sum, num;
11     node (int a, int b):sum(a),num(b){}
12     bool operator < (const node &a) const {
13         return sum > a.sum;
14     }
15 };
16 int maps[maxn][maxn], ans[maxn], arr[maxn];
17 int n;
18 void Merge (int cnt)
19 {
20     priority_queue <node> Q;
21     for (int i=0; i<n; i++)
22         Q.push (node(ans[i]+maps[cnt][0], 0));
23     for (int i=0; i<n; i++)
24     {
25         node p = Q.top ();
26         Q.pop();
27         arr[i] = p.sum;
28         if (p.num != n)
29         {
30             p.sum += maps[cnt][p.num+1] - maps[cnt][p.num];
31             p.num ++;
32             Q.push (p);
33         }
34     }
35     for (int i=0; i<n; i++)
36         ans[i] = arr[i];
37 }
38 int main ()
39 {
40     while (scanf ("%d", &n) != EOF)
41     {
42         for (int i=0; i<n; i++)
43         {
44             for (int j=0; j<n; j++)
45                 scanf ("%d", &maps[i][j]);
46             sort (maps[i], maps[i]+n);
47         }
48         for (int i=0; i<n; i++)
49             ans[i] = maps[0][i];
50         for (int i=1; i<n; i++)
51             Merge (i);
52         for (int i=0; i<n; i++)
53             printf ("%d%c", ans[i], i==n-1?'\n':' ');
54     }
55     return 0;
56 }

 

posted @ 2015-07-30 10:22  罗茜  阅读(150)  评论(0编辑  收藏  举报