luogu_1631【题解】

  题目:https://www.luogu.org/problemnew/show/P1631

  一看题面,暴力选手,先打暴力。

  非常简单的暴力,不加优化。

  代码:

  

#include<bits/stdc++.h>
#define rr(x) scanf("%d",&x)
#define pp(x) printf("%d ",x)
using namespace std;
const int maxn=100001;
int a[maxn],b[maxn];
priority_queue<int> q; 
int n;
int main()
{
    rr(n);
    for(int i=1;i<=n;i++){
        rr(a[i]);
    }
    for(int i=1;i<=n;i++){
        rr(b[i]);
        for(int j=1;j<=n;j++)
            q.push(-(a[j]+b[i]));
    }
    for(int i=1;i<=n;i++){
        pp(-q.top());
        q.pop();
    }
    return 0;
}

  果然TLE了,过了60分,还不少。

  

  不优化这个傻子算法了,开始想正解(看题解)

  果然洛谷神犇们还是没有让我失望,还是发现了理解的题解。

  第一,由于是有序的,所以a[1]一定是有最优解的,所以,将所有的b和a[1]求和,入堆。

  小根堆里用pair<int,int>,第一个int为值,第二个int为b的下标。

  为了避免重复,定义to[i]为与b[i]结合的a的下标,效果后面会见到。

  (rr是define的读入)

for(int i=1;i<=n;i++){
        rr(b[i]);to[i]=1;
        q.push(make_pair(a[1]+b[i],i));
    }

  然后就是最后的答案,每次取出值之后,取出b的下标,依照to数组,给a的下标++,再次入堆。

  全部代码如下:

#include<bits/stdc++.h>
#define rr(x) scanf("%d",&x)
#define pp(x) printf("%d ",x)
using namespace std;
const int maxn=100001;
int a[maxn],b[maxn],to[maxn];
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q; 
int n;
int main()
{
    rr(n);
    for(int i=1;i<=n;i++){
        rr(a[i]);
    }
    for(int i=1;i<=n;i++){
        rr(b[i]);to[i]=1;
        q.push(make_pair(a[1]+b[i],i));
    }
    while(n--){
        pp(q.top().first);
        int k=q.top().second;
        q.pop();
        q.push(make_pair(a[++to[k]]+b[k],k)); 
    }
    return 0;
}

 

  

posted @ 2019-04-27 16:49  ChrisKKK  阅读(150)  评论(0编辑  收藏  举报