博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷 P1631 序列合并
阅读量:5325 次
发布时间:2019-06-14

本文共 1628 字,大约阅读时间需要 5 分钟。

嗯...

 

题目链接:https://www.luogu.org/problem/P1631

 

这道题很明显的是一个堆的问题,要开一个结构体的堆(结构体中记录下标、内容、个数)...

首先,把A和B两个序列分别从小到大排序,变成两个有序队列。

然后从A和B中各任取一个数相加得到N2个和,可以把这些和看成形成了n个有序表/队列:

A[1]+B[1] <= A[1]+B[2] <= … <= A[1]+B[N]

A[2]+B[1] <= A[2]+B[2] <= … <= A[2]+B[N]

……

A[N]+B[1] <= A[N]+B[2] <= … <= A[N]+B[N]

接下来,就相当于要将这N个有序队列进行合并排序:

首先,将这N个队列的队首放入一个堆中;然后,每次取出堆中的最小值。若这个最小值来自于第k个队列,那么,就将第k个队列的下一个元素放入堆中。

时间复杂度:O(NlogN)。

细节:

1.结构体堆一定要重载运算符

2.id是这一行的第几个元素,cnt是第cnt行(也可这样理解,cnt记录第cnt个a,id记录第id个b)

AC代码:

1 #include
2 #include
3 #include
4 #include
5 6 using namespace std; 7 8 const int maxn = 100005; 9 10 int cnt;11 12 struct node{13 int id, nr, cnt;14 } p[maxn];//结构体 15 16 bool operator < (node x, node y){17 return x.nr > y.nr;18 }//重载运算符 19 20 priority_queue
q;21 22 int n, a[maxn], b[maxn];23 24 int main(){25 scanf("%d", &n);26 for(int i = 1; i <= n; i++){27 scanf("%d", &a[i]);28 p[i].id = i;29 p[i].cnt = 1;30 }31 for(int i = 1; i <= n; i++) scanf("%d", &b[i]);32 sort(a + 1, a + n + 1);33 sort(b + 1, b + n + 1);34 for(int i = 1; i <= n; i++){35 p[i].nr = a[1] + b[i];36 q.push(p[i]);37 }38 for(int i = 1; i <= n; i++){39 int ans = q.top().nr;40 printf("%d ", ans);41 node u;42 u.cnt = q.top().cnt + 1;43 u.id = q.top().id;44 q.pop();45 u.nr = a[u.cnt] + b[u.id];46 q.push(u);47 }48 return 0;49 }
AC代码

 

转载于:https://www.cnblogs.com/New-ljx/p/11246614.html

你可能感兴趣的文章
C#类与结构体究竟谁快——各种函数调用模式速度评测
查看>>
我到底要选择一种什么样的生活方式,度过这一辈子呢:人生自由与职业发展方向(下)...
查看>>
poj 题目分类
查看>>
windows 安装yaml支持和pytest支持等
查看>>
读书笔记:季羡林关于如何做研究学问的心得
查看>>
面向对象的优点
查看>>
套接口和I/O通信
查看>>
阿里巴巴面试之利用两个int值实现读写锁
查看>>
浅谈性能测试
查看>>
Winform 菜单和工具栏控件
查看>>
CDH版本大数据集群下搭建的Hue详细启动步骤(图文详解)
查看>>
巧用Win+R
查看>>
浅析原生js模仿addclass和removeclass
查看>>
Python中的greenlet包实现并发编程的入门教程
查看>>
java中遍历属性字段及值(常见方法)
查看>>
深入理解jQuery框架-框架结构
查看>>
YUI3自动加载树实现
查看>>
python知识思维导图
查看>>
当心JavaScript奇葩的逗号表达式
查看>>
App Store最新审核指南(2015年3月更新版)
查看>>