考虑一个简单的问题,两个长度为n的有序数组A和B,从每个数组中各选出一个数相加,共n2中情况,求最小的n个数。

将这n2个数拆成n个有序表:

A1+B1≤A1+B2≤...

A2+B1≤A2+B2≤...

...

An+B1≤An+B2≤...

然后用优先队列合并成一个有序表即可。队列中需要记录两个数的和s,以及在B中的下标b,

比如Aa+Bb出队以后,应该将Aa+B(b+1) = Aa + Bb - Bb + Bb+1 = s - Bb + bb+1入队

对于书上最后的一个思考问题,merge函数中对A[0]又读又写,会不会出错。答案当然是不会的,因为进入到函数内部你会发现,对A数组其实是先读后写的。

 #include <cstdio>
#include <queue>
#include <algorithm>
using namespace std; const int maxn = + ;
int a[][maxn]; void scan(int& x)
{
char c;
while(c = getchar(), c < '' || c > '');
x = c - '';
while(c = getchar(), c >= '' && c <= '') x = x* + c - '';
} struct Node
{
int sum, b;
Node(int s, int b):sum(s), b(b) {}
bool operator < (const Node& rhs) const
{ return sum > rhs.sum; }
}; void merge(int n, int* A, int* B, int* C)
{
priority_queue<Node> Q;
for(int i = ; i < n; i++) Q.push(Node(A[i]+B[], )); for(int i = ; i < n; i++)
{
Node t = Q.top(); Q.pop();
int b = t.b, sum = t.sum;
C[i] = sum;
if(b + < n) Q.push(Node(sum-B[b]+B[b+], b+));
}
} int main()
{
//freopen("in.txt", "r", stdin); int k;
while(scanf("%d", &k) == )
{
for(int i = ; i < k; i++) scan(a[][i]);
sort(a[], a[] + k);
for(int i = ; i < k; i++)
{
for(int j = ; j < k; j++) scan(a[][j]);
sort(a[], a[] + k);
merge(k, a[], a[], a[]);
} for(int i = ; i < k; i++)
{
if(i) printf(" ");
printf("%d", a[][i]);
}
puts("");
} return ;
}

代码君

UVa 11997 (优先队列 多路归并) K Smallest Sums的更多相关文章

  1. UVa 11997 K Smallest Sums 优先队列&amp;&amp;打有序表&amp;&amp;归并

    UVA - 11997 id=18702" target="_blank" style="color:blue; text-decoration:none&qu ...

  2. 11997 - K Smallest Sums(优先队列)

    11997 - K Smallest Sums You’re given k arrays, each array has k integers. There are kk ways to pick ...

  3. D - K Smallest Sums(多路归并+贪心)

    Problem K K Smallest Sums You're given k arrays, each array has k integers. There are kk ways to pic ...

  4. 【暑假】[实用数据结构]UVa11997 K Smallest Sums

    UVa11997 K Smallest Sums  题目: K Smallest Sums You're given k arrays, each array has k integers. Ther ...

  5. UVA-11997 K Smallest Sums

    UVA - 11997 K Smallest Sums Time Limit: 1000MS   Memory Limit: Unknown   64bit IO Format: %lld & ...

  6. uva 11997 优先队列

    K Smallest Sums You're given k arrays, each array has k integers. There are kk ways to pick exactly ...

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

    题意:K个数组每组K个值,每次从一组中选一个,共K^k种,问前K个小的. 思路:优先队列处理多路归并,每个状态含有K个元素.详见刘汝佳算法指南. #include<iostream> #i ...

  8. UVA 11997 K Smallest Sums 优先队列 多路合并

    vjudge 上题目链接:UVA 11997 题意很简单,就是从 k 个数组(每个数组均包含 k 个正整数)中各取出一个整数相加(所以可以得到 kk 个结果),输出前 k 小的和. 这时训练指南上的一 ...

  9. UVA 11997 K Smallest Sums (多路归并)

    从包含k个整数的k个数组中各选一个求和,在所有的和中选最小的k个值. 思路是多路归并,对于两个长度为k的有序表按一定顺序选两个数字组成和,(B表已经有序)会形成n个有序表 A1+B1<=A1+B ...

随机推荐

  1. Careercup - Facebook面试题 - 4922014007558144

    2014-05-01 02:13 题目链接 原题: Design question: Say you have hacked in to a network and can deploy your b ...

  2. Oppotunity land---China

    China is a land of opportunity.Following the development of China,every sector has made their contri ...

  3. Ubuntu 查看文件以及磁盘空间大小命令df

    (1)查看文件大小 查看当前文件夹下所有文件大小(包括子文件夹)    du -sh   # du -h 15M     ./package 16K     ./.fontconfig 4.0K    ...

  4. vi之跳到指定行

    vi里怎样跳转到某一指定行 输入 :行号 :$跳到最后一行 gg跳到第一行.

  5. Matlab 高斯分布 均匀分布 以及其他分布 的随机数

    Matlab 高斯分布 均匀分布 以及其他分布 的随机数 betarnd 贝塔分布的随机数生成器 binornd 二项分布的随机数生成器 chi2rnd 卡方分布的随机数生成器 exprnd 指数分布 ...

  6. Robot Framework 环境搭建

    一.下载软件 1.安装Python 到官网,下载Python 2.7.9:https://www.python.org/downloads/,最好选择32位版本的(64位系统也支付32位版本),然后安 ...

  7. [C++]虚函数-同名访问

    首先来看一下派生类和基类成员同名事的处理规则: 派生类内定义了一个与基类同名的成员,该现象称为同名覆盖,此时,无论派生类内部成员函数还是派生类的对象访问同名成员,如果未加任何特殊标识,则访问派生类中重 ...

  8. 用supervisor控制celery时的脚本

    注意启停的先后顺序及判断即可. 这样,在更改task之后,要重启就方便很多啦.. #!/bin/sh supervisord_count=`ps -elf | grep celery | grep - ...

  9. 【mysql的编程专题⑤】自定义函数

    用户自定义函数(user-defined function,UDF) 是一种对mysql的扩展途径,其用法与内置函数相同 创建自定义函数 语法 create function function_nam ...

  10. Swift 版本很好的卡片切换效果基于ZLSwipeableView

    前言:在这篇文章你可以学到,一些基本的Swift语法, 基本UI控件闭包等. 实际的效果,比gif图的效果好很多. 卡片切换.gif 首先需要导入ZLSwipeableView pod 'ZLSwip ...