SDUT 十日游戏(排序/优先队列)

题意:给你俩个数列,求出能够俩个数列中某俩数+和的最大的n个数,数列中的数可以用多次。
题目:https://acm.sdut.edu.cn/onlinejudge3/contests/3481/problems/K
题解:
用优先队列实现一个大根堆,先让一个序列中的所用数分别和另一个数列中的最大的数相加,然后加入优先队列,再分别取出队列的头,然后让这个a序列中的这个数加上b数列中的下一个大的值,然后加入队列,总共循环输出n次

#include <iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#define ll long long
#define inf 0x3f3f3f3f
const int N = 1e6 + 10;
using namespace std;

struct node
{
    int a,b;
    int sum;
    bool operator<(const node other)const  
    {                                   //在优先队列中实现自定义排序
        return sum<other.sum;
    }
};
bool cmp(int aa,int bb)//对俩数组排序
{
    return aa>bb;
}
int a[N],b[N];
priority_queue<node>que;

int main()
{
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    for(int i=0; i<n; i++)cin>>a[i];
    for(int i=0; i<n; i++)cin>>b[i];
    sort(a,a+n,cmp);
    sort(b,b+n,cmp);
    for(int i=0; i<n; i++)//先让一个数列和另一个数列的最大分别加和
    {                   //然后加入优先队列
        node now;
        now.a=i;     //储存a这个数列中第几大的数
        now.b=0;   //和b数列的最大相加
        now.sum=a[i]+b[0];
        que.push(now);
    }

    for(int i=0; i<n; i++)
    {
        node now=que.top(); //取出最大的
        que.pop();
        if(i!=n-1)  //控制输出,for循环就循环n次
        {
            cout<<now.sum<<" ";
        }
        else cout<<now.sum<<endl;

        now.b++;  //让目前这个第num.a大的a数组和它加的b数组中第now.b大的数中的下一个相加
        now.sum=a[now.a]+b[now.b];
        que.push(now);//然后加入队列
    }

    return 0;
}

 

posted @ 2020-12-23 11:07  Are~you~ready  阅读(108)  评论(0)    收藏  举报