暂无链接
有序表的最小和
[问题描述]
给出两个长度为n的有序表A和在A和B中各任取一个元素,可以得到n^2个和,求 这些和中最小的n个.
[输入格式]
第一行包含一个整数n(n<400000);
第二行与第三行分别有n个整数,分别代表有序表A和B。整数之间由一个空格隔开, 大小在长整型范围内,保证有序表的数据单调递增.
[输出格式]
输出共n行,每行一个整数.第i行为第i小的和。数据保证在长整型范围内.
[输入样例]
3
1 2 5
2 4 7
[输出样例]
3
4
5
题解
博主用优先队列水过了。。。
只需要建一个大根堆,初始的值用第一个元素和另一个队列挨个加一波,之后每次拿后一个元素与另一个队列的元素相加,如果比队首的值小,就弹出队首,加入新元素,当加的值比队首大时,就进入下一次比较。
这么描述比较模糊,看看代码马上就能明白。
代码
#include<bits/stdc++.h>
using namespace std;
const int M=400005;
int a[M],b[M],ans[M],r,f,n;
priority_queue<int>dui;
char c;
int read()
{
r=0;f=1;
c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c))r=(r<<1)+(r<<3)+c-'0',c=getchar();
return r;
}
void in()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
a[i]=read();
for(int i=1;i<=n;++i)
b[i]=read();
}
void out(int x)
{
if(x>9)out(x/10);
putchar(x%10+'0');
}
void ac()
{
for(int i=1;i<=n;++i)
dui.push(a[1]+b[i]);
for(int i=2;i<=n;++i)
for(int j=1;j<=n;++j)
{
if(a[i]+b[j]>dui.top())break;
if(a[i]+b[j]<dui.top())
dui.pop(),dui.push(a[i]+b[j]);
}
for(int i=1;i<=n;++i)
ans[i]=dui.top(),dui.pop();
for(int i=n;i>=1;--i)
out(ans[i]),putchar(10);
}
int main()
{
in();ac();
return 0;
}