题目大意

  有两个序列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++再推入队列中。这样便有解了。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <queue>
  5. using namespace std;
  6.  
  7. const int MAX_N = 100010, INF = 0x3f3f3f3f;
  8. int A[MAX_N], B[MAX_N];
  9.  
  10. struct Element
  11. {
  12. int AId, BId;
  13.  
  14. Element(int aId, int bId):AId(aId), BId(bId){}
  15.  
  16. bool operator < (const Element a) const
  17. {
  18. return A[AId] + B[BId] > A[a.AId] + B[a.BId];
  19. }
  20. };
  21. priority_queue<Element> q;
  22.  
  23. int main()
  24. {
  25. int n;
  26. scanf("%d", &n);
  27. for (int i = 1; i <= n; i++)
  28. scanf("%d", A + i);
  29. for (int i = 1; i <= n; i++)
  30. scanf("%d", B + i);
  31. sort(A + 1, A + n + 1);
  32. sort(B + 1, B + n + 1);
  33. for (int i = 1; i <= n; i++)
  34. q.push(Element(i, 1));
  35. for (int i = 1; i <= n; i++)
  36. {
  37. Element cur = q.top();
  38. q.pop();
  39. printf("%d ", A[cur.AId] + B[cur.BId]);
  40. if (cur.BId < n)
  41. {
  42. cur.BId++;
  43. q.push(cur);
  44. }
  45. }
  46. return 0;
  47. }

  

luogu1631 序列合并的更多相关文章

  1. 洛谷P1631 序列合并

    P1631 序列合并 236通过 657提交 题目提供者xmyzwls 标签堆 难度普及+/提高 提交该题 讨论 题解 记录 最新讨论 为什么不行? 题目描述 有两个长度都是N的序列A和B,在A和B中 ...

  2. P1631 序列合并

    P1631 序列合并 有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N^2N2个和,求这N^2N2个和中最小的N个. 对于100%的数据中,满足1<=N<=100000. ...

  3. 【洛谷】P1631: 序列合并

    P1631 序列合并 题目描述 有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N2个和,求这N2个和中最小的N个. 输入输出格式 输入格式: 第一行一个正整数N: 第二行N个整数Ai​ ...

  4. 求两个有序序列合并成新有序序列的中位数,求第k小数

    此算法涉及一个重要数学结论:如果A[k/2-1]<B[k/2-1],那么A[0]~A[k/2-1]一定在第k小的数的序列当中,可以用反证法证明. 算法思想如下: 1,假设A长度为m,B长度为n, ...

  5. [题解](堆)luogu_P1631序列合并

    思路来自题解 作者: Red_w1nE 更新时间: 2016-11-13 20:46 在Ta的博客查看  72 最近有点忙 没时间贴代码了== [分析] 首先,把A和B两个序列分别从小到大排序,变成两 ...

  6. [luoguP1631] 序列合并(堆 || 优先队列)

    传送门 首先,把A和B两个序列分别从小到大排序,变成两个有序队列.这样,从A和B中各任取一个数相加得到N2个和,可以把这些和看成形成了n个有序表/队列: A[1]+B[1] <= A[1]+B[ ...

  7. 洛谷2085最小函数值(minval) + 洛谷1631序列合并

    题目描述 有n个函数,分别为F1,F2,-,Fn.定义Fi(x)=Ai*x^2+Bi*x+Ci (x∈N*).给定这些Ai.Bi和Ci,请求出所有函数的所有函数值中最小的m个(如有重复的要输出多个). ...

  8. 洛谷 - P1631 - 序列合并 - 堆

    https://www.luogu.org/problemnew/show/P1631 序列a中每个数首先都和序列b中的最小元素配对(虽然好像不是很必要这么早插进来?) 每次从堆顶取出最小的和输出答案 ...

  9. P1631 序列合并 洛谷

    https://www.luogu.org/problem/show?pid=1631 题目描述 有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N^2个和,求这N^2个和中最小的N个. ...

随机推荐

  1. iOS动画——DynamicAnimate

    力学动画 以dynamicAnimate为首的力学动画是苹果在iOS7加入的API,里面包含了很多力学行为,这套API是基于Box2d实现的.其中包含了重力.碰撞.推.甩.和自定义行为. 涉及到的类如 ...

  2. Android基于HttpUrlConnection类的文件下载

    /** * get方法的文件下载 * <p> * 特别说明 android中的progressBar是google唯一的做了处理的可以在子线程中更新UI的控件 * * @param pat ...

  3. Android开发问题-真机调试连接

    出现“no debuggable processes”可以: 1)尝试Tools->android->Enable ADB Intergration使之选中: 2)换一根数据线试试. 初次 ...

  4. Beta Edition [ Group 1 ]

    DeltaFish Beta Edition 一.七月开发过程 小组会议 DeltaFish 校园物资共享平台 第八次小组会议 GITHUB https://github.com/DeltaFishS ...

  5. 初学JSP_内置对象

    out内置对象: 表单,表单常用的的提交方式

  6. S3C2440中断

    韦东山老师一期中断课程学习: 总结: 程序启动后工作流程,程序从0地址开始执行Reset  --> 重定位  -->ldr pc,=main [绝对跳转到SDRAM中执行main()函数] ...

  7. Python 内置函数 day4

    import random s = 'abczfg' st= {3,4,9,1,8} print(dir(random))#打印模块内的方法,输出模块/变量可以调用的方法 print(dir(s))# ...

  8. JavaScript day2(变量)

    变量(variable) 允许计算机以一种动态的形式来存储和操作数据,通过操作指向数据的指针而不是数据本身来避免了内存泄露,变量(Variable)的名字可以由数字.字母.$ 或者 _组成,但是不能包 ...

  9. 计蒜客 劫富济贫 (Trie树)

    链接 : Here! 思路 : Trie树裸题, 由开始给出的名字建一棵字典树, 然后每次查询一下抢♂劫的人名是否在字典树中, 复杂度也不清楚是多少, 反正是没给出 $M$ 的范围, 开始时用 $ha ...

  10. linux 头文件和库文件的设置

    GCC/G++会查找系统默认的include和link的路径,以及自己在编译命令中指定的路径.自己指定的路径就不说了,这里说明一下系统自动搜索的路径. [1]include头文件路径 除了默认的/us ...