题目大意

  有两个序列A,B,在A和B中各取一个数相加能得到$n^2$个和。求出这些和前n小的数字。

题解

  首先这道题不可以用自己想的什么A序列B序列各两个指针的自己发明的模拟算法,用这样的算法只能是绝路一条。

  此题入手点在于优化暴力。暴力算法是枚举所有的$A_i+B_j$,排个序,然后一个个输出。我们优化之处便是如何动态枚举$A_i,B_j$。

  此时我曾想对两个数组都动态,这样想就走到了死胡同。

  我们可以让A不动态,B动态,也就是优先队列里储存的数对里包含所有的$A_i$,但每个$A_I$只对应一个$B_j$。每次出队时,将$A_i$对应的$B_j$的j++再推入队列中。这样便有解了。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std; const int MAX_N = 100010, INF = 0x3f3f3f3f;
int A[MAX_N], B[MAX_N]; struct Element
{
int AId, BId; Element(int aId, int bId):AId(aId), BId(bId){} bool operator < (const Element a) const
{
return A[AId] + B[BId] > A[a.AId] + B[a.BId];
}
};
priority_queue<Element> q; int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", A + i);
for (int i = 1; i <= n; i++)
scanf("%d", B + i);
sort(A + 1, A + n + 1);
sort(B + 1, B + n + 1);
for (int i = 1; i <= n; i++)
q.push(Element(i, 1));
for (int i = 1; i <= n; i++)
{
Element cur = q.top();
q.pop();
printf("%d ", A[cur.AId] + B[cur.BId]);
if (cur.BId < n)
{
cur.BId++;
q.push(cur);
}
}
return 0;
}

  

最新文章

  1. 模拟搭建Web项目的真实运行环境(五)
  2. 关于MVC4.0中@Styles.Render用法与详解
  3. C++11:新式的字符串字面常量(String Literal)
  4. 重载Python FTP_TLS 实现Implicit FTP Over TLS方式下载文件
  5. Asp.net使用代码修改配置文件的节点值
  6. DOM_05之DOM、BOM常用对象
  7. 求最长回文子串 - leetcode 5. Longest Palindromic Substring
  8. 一起学HTML基础-利用CSS和JavaScript制作一个切换图片的网页
  9. openstack(liberty): devstack之screen
  10. linux 从命令行自动识别文件并将其打开的命令
  11. Mac系统Finder访问资源库文件夹
  12. apache开源项目--log4j
  13. ios开发应用内实现多语言自由切换
  14. 得到Android keystore签名的命令方法
  15. python面向对象的三大特征
  16. 对 Service中sqlsession对象的优化
  17. [leetcode 12] Inter to Roman
  18. docker镜像基本操作一
  19. Jmeter入门--参数化、集合点
  20. Java Web开发基础(3)-JSTL

热门文章

  1. vue项目杂记
  2. jQuery文档就绪
  3. Ajax——跨域访问
  4. JS——sort
  5. SQl基本操作——try catch
  6. Nrpe 插件安装教程
  7. mysql_数据查询_连接查询
  8. case....when ...多重判断
  9. Scrapy下载器中间件用法示例
  10. 第十三节:pandas之groupby()分组