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 }
时间: 2024-10-31 07:42:35

Zznu 1913: yifan and matrix (多路归并)的相关文章

C++ 模板实现败者树,进行多路归并

项目需要实现一个败者树,今天研究了一下,附上实现代码. 几点说明: 1. 败者树思想及实现参考这里:http://www.cnblogs.com/benjamin-t/p/3325401.html 2. 多路归并中的“多路”的容器使用的是C语言数组 + 数组长度的实现(即 const ContainerType* ways, size_t num ),而没有用STL中的容器,这是因为项目需要如此,日后再改成STL容器: 3. _losers 存储下标,用的是 int 类型,还需要修改.程序中其他

UVA 11997 K Smallest Sums (多路归并)

从包含k个整数的k个数组中各选一个求和,在所有的和中选最小的k个值. 思路是多路归并,对于两个长度为k的有序表按一定顺序选两个数字组成和,(B表已经有序)会形成n个有序表 A1+B1<=A1+B2 A2+B1<=A2+B2 ... An+B1<=An+B2 在学习的归并排序的时候是把两个有序的表合并成一个,每次比较只在两个元素之间进行,所以只需要用>比较, 而现在需要同时合并n个有序表,优先队列(堆)就派上用场了.类似归并排序用i和j维护有序表当前考虑元素, 合并的时候,每次取出的

数据结构:外排序-多路归并

外排序 外排序问题的出现,主要是因为内存不够.当需要排序的数据量过多,以至于无法一次性把所有的数据都放入内存,这导致了外排序问题的出现.解决大数据量排序的方法是:先分块排序,后进行块合并. 外排序步骤 把原数据分成几段读入内存,以至于每一块都可以完整的在内存中进行排序,排序好后,写入外部存储设备. 归并已排序好的数据块. 这就是归并排序在外排序中的应用. 对每块数据进行排序,可以使用各种内排序方法:快速排序.归并排序.堆排序等.这个比较简单,下面模拟一个对排序好的数据块进行归并的过程. #inc

uva 11997 K Smallest Sums 优先队列处理多路归并问题

题意:K个数组每组K个值,每次从一组中选一个,共K^k种,问前K个小的. 思路:优先队列处理多路归并,每个状态含有K个元素.详见刘汝佳算法指南. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<stack> 5 #include<queue> 6 #include<vector> 7 #include<map> 8 #includ

C++ 多态 从不同数据源获取数据 多路归并

定义一个基类,用基类的指针分别指向不同的子类... #include <iostream> #include <stdio.h> #include <algorithm> #include <vector> using namespace std; class ListNode { public: int val; ListNode* next; ListNode(int x) : val(x), next(NULL) { } }; class DataSo

磁盘排序算法(多路归并、位图)

问题描述 输入:一个最多包含n个正整数的文件,每个数都小于n,其中n=107.如果在输入文件中有任何正数重复出现就是致命错误.没有其他数据与该正数相关联. 输出:按升序排列的输入正数的列表. 约束:最多有1MB的内存空间可用,有充足的磁盘存储空间可用.运行时间最多几分钟,运行时间为10秒就不需要进一步优化. 程序设计与实现概要: 应用位图或位向量表示集合.可用一个10位长的字符串来表示一个所有元素都小于10的简单的非负整数集合,例如,可以用如下字符串表示集合{1,2,4,5,8}: 0 1 1

UVA 11997--K Smallest Sums+优先队列用于多路归并

题目链接:点击进入 先考虑两个数组A,B的情况,这样总共有n^2种情况;将A,B数组排序后,我们可以将所有情况组织成n张表: 表1: A[1]+B[1]<=A[1]+B[2]<=--<=A[1]+B[n]. 表2: A[2]+B[1]<=A[2]+B[2]<=--.<=A[2]+B[n]. --. 表n: A[n]+B[1]<=A[n]+B[2]<=--..<=A[n]+B[n] 这n张表都是有序的,所以可以以多路归并的思想求出其中前n个最小的元素.对

外排序 &amp; 败者树 &amp; 多路归并-学习

来来来,根据这篇文章,学一下败者树吧: http://blog.csdn.net/whz_zb/article/details/7425152 一.胜者树 胜者树的一个优点是,如果一个选手的值改变了,可以很容易地修改这棵胜者树.只需要沿着从该结点到根结点的路径修改这棵二叉树,而不必改变其他比赛的结果. 二.败者树 败者树是胜者树的一种变体.在败者树中,用父结点记录其左右子结点进行比赛的败者,而让胜者参加下一轮的比赛.败者树的根结点记录的是败者,需要加一个结点来记录整个比赛的胜利者.采用败者树可以

外排序 &nbsp; 败者树 &nbsp; 多路归并

一.外排序 排序按数据存在的位置不同分为内排序和外排序 内排序:数据都在内存中,选择合适的排序方法对数据进行排序,比如选择排序.快速排序等 衡量内排序的效率是数据的比较次数 外排序:数据无法全部加载到内存中,只能不断在外部存储器和内存中进行交换完成排序 衡量外排序的效率是内存与外村的交换次数 外排序是针对大文件的数据排序,内存中无法加载这个大文件,把这个文件分为k个小文件,分别排序后合并 http://blog.csdn.net/msdnwolaile/article/details/52084