序列合并 洛谷1631 堆

来源:互联网 发布:淘宝助理上传中断 编辑:程序博客网 时间:2024/06/10 05:39

题目描述


有两个长度都是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 100001using 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;}
0 0
原创粉丝点击