wikioi 1245最小N个和

本文介绍了一种算法,用于从两个长度为N的序列中选取元素组合成和,并找到这些和中最小的N个值。通过排序和使用大根堆的数据结构来实现高效的查找。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述 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

数据范围及提示 Data Size & Hint

【数据规模】 对于 100%的数据,满足 1≤N≤100000。


题解:将两个序列按从小到大排序(实际数据已经有序),对于A[i]和B[j],a[i]+b[j]<a[i]+b[j+1]必然成立。

           于是我们建一个大根堆,保存最小的N个和。先将A[1]和B的和放入堆中,之后的A[I]和B[J]的和每次与堆顶比较,大于则直接break,小于则置换堆顶即可。输出时逆序输出堆中元素


#include<queue>  
#include<cstdio>  
#include<iostream>  
#define MAXN 1000000  
using namespace std;   
priority_queue<int> heap;  
int n;  
int a[MAXN+5],b[MAXN+5],ans[MAXN+5];  
  
int main()  
{  
    scanf("%d",&n);  
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);  
    for (int i=1;i<=n;i++) scanf("%d",&b[i]);  
    for (int i=1;i<=n;i++) heap.push(a[1]+b[i]);  
    for (int i=2;i<=n;i++)  
    {  
        for (int j=1;j<=n;j++)  
        {  
            int now=a[i]+b[j];  
            if (now<heap.top())  
            {  
                heap.pop();  
                heap.push(now);  
            }  
            else break;  
        }  
    }  
    for (int i=1;i<=n;i++)  
    {  
        ans[i]=heap.top();  
        heap.pop();  
    }   
    for (int i=n;i>=1;i--) printf("%d ",ans[i]);  
    return 0;  
}  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值