问题 M: 序列合并

题目描述

有两个长度都是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.

输出

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

样例输入

3
2 6 6
1 4 8

样例输出

3 6 7 

提示

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

解:

可以从题目中得出以下信息:

A1+B1<=A1+B2<=A1+B3...<=A1+Bn

A2+B1<=A2+B2<=A2+B3...<=A2+Bn

...

An+B1<=An+B2<=An+B3...<=An+Bn

所以计算的时候,先算第一列的最小值,然后模拟,一直到第n列,使用优先级队列

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = 100000 + 10;
struct Item
{
    ll s,b;
    Item(int s, int b):s(s),b(b)    {};
    bool operator < (const Item& rhs) const{
    return s > rhs.s;
    }
};
ll a[M],b[M],n;
priority_queue<Item> q;
int main()
{
    cin>>n;
    for(int i = 1; i <= n; i++)
        cin>>a[i];
    for(int i = 1; i <= n; i++)
        cin>>b[i];
    for(int i = 1; i <= n; i++)
        q.push(Item(b[1]+a[i],1));
    for(int i = 0; i < n; i++)
    {
        cout<<q.top().s<<" ";
        Item item = q.top();    q.pop();
        int index = item.b;
        if(index+1 <= n) q.push(Item(item.s-b[index]+b[index+1],index+1));
    }
    return 0;
}

Okkkkk,hahaha

猜你喜欢

转载自www.cnblogs.com/lwsh123k/p/9455050.html