codevs 1245 最小的N个和
1245 最小的N个和
有两个长度为 N 的序列 A 和 B,在 A 和 B 中各任取一个数可以得到 N^2 个和,求这N^2 个和中最小的 N个。
第一行输入一个正整数N;第二行N个整数Ai 且Ai≤10^9;第三行N个整数Bi,
且Bi≤10^9
输出仅一行,包含 n 个整数,从小到大输出这 N个最小的和,相邻数字之间用
空格隔开。
5
1 3 2 4 5
6 3 4 1 7
2 3 4 4 5
【数据规模】 对于 100%的数据,满足 1≤N≤100000。
堆的基本操作+贪心
堆的基本操作讲解,见随笔:讲解——堆http://www.cnblogs.com/TheRoadToTheGold/p/6238795.html
设输入数据存在数组a[]和b[]中,heap[]为大根堆
为什么题目要求最小的n个,我们却要维护大根堆呢?看完以下几个步骤再说。
1、排序:题目要求输出最小的n个数,所以先将两个数组从小到大排序
2、heap[]初始化:因为固定输出n个数,所以把排序之后的数组a[1]依次与b[]的每一个数相加,和加入heap[]中
3、从a[2]开始枚举每一个数,如果a中的第i个+b中的第1个(即b中最小的一个)>=heap[1](即堆中最大的元素),那么结束枚举。因为a是递增的,b也是递增的,后面的相加的和会更大。
如果a中第i个+b中第j个>=heap[1],那么枚举a的下一个,因为b中元素递增,与同一个a相加后更大;枚举a的下一个,b从第一个开始,可能会产生更小的。
4、步骤3中,在每加入一个元素之前,都要删除堆中第一个(即最大的),因为加入的元素一定小于堆中第一个元素。
5、取出堆中的每一个元素,因为是大根堆,而题目要最小的n个,所以倒叙存储。
6、输出答案
由此可见为什么要维护大根堆了吧!利用大根堆的第一个元素可以快速判断a,b中的数还有没有枚举的必要。
有人可能说了,那我维护一个小根堆,不是也能判断吗?
的确,也能判断。
但小根堆中最大的元素查找时间复杂度为o(n/2),大根堆为O(1)。当然是大根堆快啦。
此处容易有一个理解偏差:认为小根堆中最大的元素就是heap[n],实际不是这样:

#include<cstdio>
#include<algorithm>
using namespace std;
int n,a[],b[],heap[],s,ans[];//s表示heap[]中的元素个数
int init()//读入优化
{
int x=,f=;char c=getchar();
while(c<''||c>'') {if(c=='-') f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
void insert(int k)//往堆中加入元素k
{
s++;
int p=s;
heap[s]=k;
while(p>&&k>heap[p/])
{
heap[p]=heap[p/];
p/=;
}
heap[p]=k;
}
void heapify(int t)//维护堆
{
int left=t*,right=t*+;
int maxn=t;
if(left<=s) maxn=heap[maxn]>heap[left] ? maxn:left;
if(right<=s) maxn=heap[maxn]>heap[right] ? maxn:right;
if(maxn!=t)
{
swap(heap[maxn],heap[t]);
heapify(maxn);
}
}
int get()//取出堆中最大值
{
int top=heap[];
heap[]=heap[s];
s--;
heapify();
return top;
}
int main()
{
n=init();
for(int i=;i<=n;i++) a[i]=init();
for(int i=;i<=n;i++) b[i]=init();
sort(a+,a+n+);//排序,对应第1步
sort(b+,b+n+);
for(int i=;i<=n;i++) insert(a[]+b[i]);//堆得初始化,对应第2步
for(int i=;i<=n;i++)//对应第3步
{
if(heap[]<=a[i]+b[]) break;
for(int j=;j<=n;j++)
{
if(heap[]<=a[i]+b[j]) break;
get();//对应第5步
insert(a[i]+b[j]);
}
}
while(s) ans[s]=get();//对应第6步
for(int i=;i<=n;i++) printf("%d ",ans[i]);//对应第7步
}
刚开始超时一个点,原因是两个判断break的语句没有加等号。只想着相等的元素也要输出,却忽略了判断的是堆中最大的元素,相不相等无所谓。
超时的数据:n=10000,然后20000个1,所有的和都是2
codevs 1245 最小的N个和的更多相关文章
- CODEVS 1245 最小的N个和 堆+排序
原题链接 http://codevs.cn/problem/1245/ 题目描述 Description 有两个长度为 N 的序列 A 和 B,在 A 和 B 中各任取一个数可以得到 N^2 个和,求 ...
- AC日记——最小的N个和 codevs 1245
1245 最小的N个和 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 有两个长度为 N ...
- 最小的N个和(codevs 1245)
1245 最小的N个和 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 有两个长度为 N ...
- 1245 最小的N个和
1245 最小的N个和 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 有两个长度为 N 的序列 A 和 B, ...
- 1245 最小的N个和(前k小ai+bi)
1245 最小的N个和 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 有两个长度为 N ...
- code vs 1245 最小的N个和
1245 最小的N个和 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 有两个长度为 N 的序列 A ...
- Codevs No.1245 最小的N个和
2016-05-31 18:52:15 题目链接: 最小的N个和 Codevs No.1245 题目大意: 给两个等长数列,各取一个数求和,找到最小的N组 解法: 堆优化的大暴力 直接枚举所有可能在最 ...
- codevs 2796 最小完全图
2796 最小完全图 http://codevs.cn/problem/2796/ 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 若一个图的每一对不 ...
- Codevs 1904 最小路径覆盖问题
1904 最小路径覆盖问题 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 大师 Master 传送门 题目描述 Description 给定有向图G=(V,E).设P 是G 的一个 ...
随机推荐
- Oracle基础维护02-表、主键、索引、表结构维护手册
目录 一.项目新建表.主键.索引注意事项 二.举例说明建表.主建.索引的操作方法 2.1 设定需求如下 2.1.1 查询数据库有哪些表空间 2.1.2 本文档假设数据库有这两个业务用户的表空间 2.2 ...
- Oracle数据库异机升级
环境: A机:RHEL5.5 + Oracle 10.2.0.4 B机:RHEL5.5 需求: A机10.2.0.4数据库,在B机升级到11.2.0.4,应用最新PSU补丁程序. 目录: 一. 确认是 ...
- 你真的会玩SQL吗?简单的数据修改
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- 介介介是一个ORM
介个是一个ORM,介个ORM基于Dapper扩展. 为什么需要一个ORM呢? 支持简单的LINQ查询 但是不能连表查询,why?why?why?为什么不能连接查询 ^.^ ok.但是就是不支持.哈哈哈 ...
- 模仿东京首页banner轮播,京东新闻上下滚动动画实现(动画实现)
接着上篇 微信小程序-阅读小程序demo写:http://www.cnblogs.com/muyixiaoguang/p/5917986.html 首页banner动画实现 京东新闻上下动画实现 想着 ...
- 自动绘图AI:程序如何画出动漫美少女
序 全新的图形引擎与AI算法,高效流畅地绘出任何一副美丽的图像. IDE:VisualStudio 2015 Language:VB.NET/C# Graphics:EDGameEngine 第一节 ...
- Java进击C#——应用开发之Asp.net
本章简言 上一章中笔者讲到关于Linq和EF的用法.并以hibernate来进行讲解.那么本章笔者来讲一下C#的Asp.Net.即是在B/S模式下开发.现在企业大部分的业务都是面向B/S模式的.所以对 ...
- Markdown通用的常用语法说明
前言 Markdown 是一种轻量级的 标记语言,语法简洁明了.学习容易,还具有其他很多优点,目前被越来越多的人用来写作使用. Markdown具有一系列衍生版本,用于扩展Markdown的功能(如表 ...
- C# 本质论 第二章 数据类型
浮点数的精度由有效数字的个数决定.除非用分数表示时,分母恰好是2的整数次幂,否则用二进制浮点类型无法准确地表示该数(0.1,表示成分数是1/10,分母10不能用有限二进制表示),二进制浮点类型无法准确 ...
- WPF DataGrid 行选中相关
DataGrid选中行是有自带SelectionChanged的,可是当需要重复选中同一行时,该事件就不会触发了. 后来反复查资料找到了DataGrid上有个DataGridRow. DataGrid ...