序列合并 洛谷1631 堆

14 篇文章 0 订阅

题目描述


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

输入格式:


第一行一个正整数N;

第二行N个整数Ai,满足Ai<=Ai+1且Ai<=10^9;

第三行N个整数Bi, 满足Bi<=Bi+1且Bi<=10^9.

[数据规模]


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

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

输出格式:


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

Solution


类似之前的最小函数值,分别记录第一排乘到哪一位,每次取堆顶然后后移压入

Code


#include <stdio.h>
#include <string.h>
#include <queue>
#include <vector>
#include <algorithm>
#define rep(i, st, ed) for (int i = st; i <= ed; i += 1)
#define drp(i, st, ed) for (int i = st; i >= ed; i -= 1)
#define fill(x, t) memset(x, t, sizeof(x))
#define N 100001
using std:: vector;
vector<int> v;
vector<int> a;
struct rec{
    int x, cal;
    bool operator <(const rec &b) const{
        rec a = *this;
        return a.x + v[a.cal] > b.x + v[b.cal];
    }
};
inline int read(){
    int num = 0, v = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9'){
        if (ch == '-'){
            v = -1;
        }
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9'){
        num = (num << 1) + (num << 3) + ch - '0';
        ch = getchar();
    }
    return num * v;
}
using std:: priority_queue;
int main(void){
    int n = read();
    priority_queue<rec> heap;
    rep(i, 1, n){
        int x = read();
        a.push_back(x);
    }
    rep(i, 1, n){
        int x = read();
        v.push_back(x);
    }
    sort(v.begin(), v.end());
    drp(i, n - 1, 0){
        heap.push((rec){a[i], 0});
    }
    while (n --){
        rec prt = heap.top(); heap.pop();
        printf("%d ", prt.x + v[prt.cal]);
        heap.push((rec){prt.x, prt.cal + 1});
    }
    printf("\n");
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值