P1631 序列合并 洛谷

https://www.luogu.org/problem/show?pid=1631

题目描述

有两个长度都是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个最小的和,相邻数字之间用空格隔开。

输入输出样例

输入样例#1:
3
2 6 6
1 4 8
输出样例#1:
3 6 7
 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstdio>
 4 #define N 100015
 5 
 6 using namespace std;
 7 
 8 int n,size,a[N],b[N];
 9 int heap[N],ans[N];
10 
11 void push(int x)
12 {
13     heap[++size]=x;
14     int now=size,next;
15     while(now>1)
16     {
17         next=now/2;
18         if(heap[next]>=heap[now])    break;
19         swap(heap[next],heap[now]);
20         now=next;
21     }
22     
23 }
24 
25 void pop()
26 {
27     heap[1]=heap[size--];
28     int now=1,next;
29     while(now*2<=size)
30     {
31         next=now*2;
32         if(next<size&&heap[next]<heap[next+1])    next++;
33         if(heap[now]>=heap[next])    break;
34         swap(heap[now],heap[next]);
35         now=next;
36     }
37 }
38 
39 int main()
40 {
41     scanf("%d",&n);
42     for(int i=1;i<=n;i++)    scanf("%d",&a[i]);
43     for(int i=1;i<=n;i++)    scanf("%d",&b[i]);
44     sort(a+1,a+n+1);
45     sort(b+1,b+n+1);
46     for(int i=1;i<=n;i++)    push(a[1]+b[i]);
47     for(int i=2;i<=n;i++)
48         for(int j=1;j<=n;j++)
49         {
50             if(heap[1]>a[i]+b[j])
51             {
52                 pop();
53                 push(a[i]+b[j]);
54             }
55             else break;
56         }
57     for(int i=1;i<=n;i++)
58     {
59         ans[i]=heap[1];
60         pop();
61     }
62     while(n--)
63     {
64         printf("%d ",ans[n+1]);
65     }
66     return 0;
67 }
优先队列T2ge
——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
原文地址:https://www.cnblogs.com/Shy-key/p/6607409.html