题目描述
Description
有两个长度为 N 的序列 A 和 B,在 A 和 B 中各任取一个数可以得到 N^2 个和,求这N^2 个和中最小的 N个。
输入描述
Input Description
第一行输入一个正整数N;第二行N个整数Ai 且Ai≤10^9;第三行N个整数Bi,
且Bi≤10^9
输出描述
Output Description
输出仅一行,包含 n 个整数,从小到大输出这 N个最小的和,相邻数字之间用
空格隔开。
样例输入
Sample Input
5
1 3 2 4 5
6 3 4 1 7
样例输出
Sample Output
2 3 4 4 5
建造二叉最小堆,维护编号为1的点即可
#include<bits/stdc++.h>
#define maxn 120000
using namespace std;
long long a[maxn],b[maxn];
struct ss
{
long long x,y;
long long w;
};
struct ss s[3*maxn];
long long number=0;
long long n;
void Swap(long long aaa,long long bbb)
{
struct ss temp;
temp=s[aaa];
s[aaa]=s[bbb];
s[bbb]=temp;
}
void siftdown(long long i)
{
long long t,flag=0;
while(i*2<=n&&!flag)
{
if(s[i].w>s[i*2].w)
t=i*2;
else t=i;
if(i*2+1<=n)
{
if(s[t].w>s[i*2+1].w)
t=2*i+1;
}
if(t!=i)
{
Swap(t,i);
i=t;
}
else flag=1;
}
return ;
}
void create()
{
long long i;
for(long long i=number/2;i>=1;i--)
siftdown(i);
}
int main()
{
ios::sync_with_stdio(false);//!!!important!!!
cin>>n;
for(long long i=1;i<=n;i++)
cin>>a[i];
for(long long i=1;i<=n;i++)
cin>>b[i];
sort(a+1,a+n+1);
sort(b+1,b+n+1);
for(long long i=1;i<=n;i++)
{
s[i].x=i;
s[i].y=1;
s[i].w=a[i]+b[1];
}
create();
long long number=n;
while(number--)
{
cout<<s[1].w<<" ";
long long xx=s[1].x,yy=s[1].y+1;
long long ww=a[xx]+b[yy];
s[1].x=xx;
s[1].y=yy;
s[1].w=ww;
siftdown(1);
}
return 0;
}
其实可以用优先队列但是我不会用,没办法啦,写个堆凑合一下~