【清北前紧急补课11】优先队列的正确使用方法

题目描述

有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到 N2N^2N2 个和,求这 N2N^2N2 个和中最小的N个。

输入输出格式

输入格式:

第一行一个正整数N;

第二行N个整数 AiA_iAi , 满足 Ai≤Ai+1A_i\le A_{i+1}AiAi+1Ai≤109A_i\le 10^9Ai109 ;

第三行N个整数 BiB_iBi , 满足 Bi≤Bi+1B_i\le B_{i+1}BiBi+1Bi≤109B_i\le 10^9Bi109 .

【数据规模】

对于50%的数据中,满足1<=N<=1000;

对于100%的数据中,满足1<=N<=100000。

输出格式:

输出仅一行,包含N个整数,从小到大输出这N个最小的和,相邻数字之间用空格隔开。

输入输出样例

输入样例#1: 复制
3
2 6 6
1 4 8
输出样例#1: 复制
3 6 7


不难看出要使用优先队列,但是很明显如果循环到n会T那么几个点 那就理性来分析一下
如果我们i和j两个循环 分别枚举到√n 那么我们就能得到n个数据 但是很显然所求有的并不在n中 那么对于枚举到√n所获得的a[i]+a[j]<a[i']+a[j']必然要更新 更新的i' 和j'一定是一个在√n以内 另一个在√n到2*√n
因为已经排完序了 所以在2*√n到3*√n之间乃至更大所找的的用来更新的i'和j'显然不如之前的优
那么我们只要循环到2*√n就可以啦
上代码
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<queue>
 7 using namespace std;
 8 priority_queue<int,vector<int>,greater<int> > q;
 9 int main(){
10     int n,a[100001],b[100001],s,to[100001];
11     cin>>n;
12     for(int i=1;i<=n;i++){
13         cin>>a[i];
14     }
15     for(int i=1;i<=n;i++){
16         cin>>b[i];
17     }
18     sort(a+1,a+n+1);
19     sort(b+1,b+n+1);
20     
21     for(int i=1;i<=2*sqrt(n);i++)
22     for(int j=1;j<=2*sqrt(n);j++){
23         s=a[i]+b[j];
24         q.push(s);
25     }
26     for(int i=1;i<=n;i++){
27         cout<<q.top()<<" ";
28         q.pop();
29     }
30 } 

 

posted @ 2018-08-11 15:29  东方的古文明  阅读(171)  评论(0编辑  收藏  举报