2269: minval
时间限制: 3 Sec 内存限制: 256 MB
提交: 621 解决: 62
[提交][状态][讨论版][命题人:外部导入]
题目描述
有两个长度为N的序列A和B,在A和B中各任取一个数相加可以得到N2个和,求这N2个和中最小的N个。
输入
第一行输入一个正整数N(1<=N<=100000);
第二行N个整数Ai且Ai<=109;第三行N个整数Bi且Bi<=109。
输出
输出仅一行,包含n个整数,从小到大输出这n个最小的和,相邻数字之间用空格隔开。
样例输入
5
1 3 2 4 5
6 3 4 1 7
样例输出
时间限制: 3 Sec 内存限制: 256 MB
提交: 621 解决: 62
[提交][状态][讨论版][命题人:外部导入]
题目描述
有两个长度为N的序列A和B,在A和B中各任取一个数相加可以得到N2个和,求这N2个和中最小的N个。
输入
第一行输入一个正整数N(1<=N<=100000);
第二行N个整数Ai且Ai<=109;第三行N个整数Bi且Bi<=109。
输出
输出仅一行,包含n个整数,从小到大输出这n个最小的和,相邻数字之间用空格隔开。
样例输入
5
1 3 2 4 5
6 3 4 1 7
样例输出
2 3 4 4 5
按大白书上的原理,先对两个数组排序,用一个二元组来标记两个数的和,和b数组的当前位置,放入优先队列中。每一次把最小的取出来,再把最小和s-b[i]+b[i+1]放入队列,循环n次就可以了;
#include<stack>
#include<queue>
#include<math.h>
#include<vector>
#include<string>
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<map>
#define maxn 5000005
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define inf 0x3f3f3f
using namespace std;
ll a[maxn];
ll b[maxn];
ll c[maxn];
struct node{
ll s,b;
node(ll s,ll b):s(s),b(b){}
bool operator <(const node& rhs)const{
return s>rhs.s;
}
};
void m(ll *A,ll *B,ll *C,int n){
priority_queue<node>q;
for(int i=0;i<n;i++){
q.push(node(A[i]+B[0],0));
}
for(int i=0;i<n;i++){
node d=q.top();q.pop();
C[i]=d.s;
int b=d.b;
if(b+1<n)q.push(node(d.s-B[b]+B[b+1],b+1));
}
}
int main(){
int n;
while(~scanf("%d",&n)){
for(int i=0;i<n;i++)scanf("%lld",&a[i]);
for(int j=0;j<n;j++)scanf("%lld",&b[j]);
sort(a,a+n);
sort(b,b+n);
m(a,b,c,n);
for(int i=0;i<n;i++){
cout<<c[i]<<" ";
}
}
}