[Data Structure·Heap] The first n small elements of the sequence sum (heap sort)

topic description

Question: The first n small elements of the sequence sum
Given two ordered lists A and B of length n, one of each of A and B is randomly selected, and n^2 sums can be obtained. Find the smallest n of these sums.

input and output format

Input format:

There are three lines of input data.
  On the first line, an integer value n ( n <= 10^4 ).
  The second and third lines each have n integers sorted from small to large, and there is a space between each integer. (every integer less than 2^30)

Output format:

Output one line of data, these and the smallest n numbers, output from small to large, with a space between each integer.

Input and output samples

Input example #1:

3
2 6 6
1 4 8

Sample output #1:

3 6 7

train of thought

When I first saw this question, I thought it was a water question , no, it was just n 2 n^2n2 numbers sorted and then output? As a result, it took two minutes to write the code and then directlyTLE...
Then I listened to the teacher's comment and found that it was indeed awater problem
. The idea is probably:
1. Build alarge root heap(priority queue) to maintainthe sum ofthe a arrayandthe b array
! ! ! It is a big root pile, not a small root pile! ! ! Regardless of whether it is sorted from small to large, the small root pile is builtbecause the top of the big root pile is the largest, which is equivalent to a goalkeeper. All numbers must pass through it if they want to enter the pile. We can use this top of the pile to filter all numbers.
2.Double cycleviolenceenumerates thearray aandarray b,but! ! ! Pruning is possible here! ! ! Since the input is twoordered lists, as long as one ofthe addedsums is larger than the top of the big root pile, then the sumaddedwill be larger than the top of the big root pile, and it is impossible to enter the pile. So justbreakdirectlyarray aandarray b
smaller than the topof the heap into the heap4. At this time we can get a queue from large to small (big top heap), and finally turn it upside down and output it
AC la

If you don't understand it, take a look at the code and comments:

AC code

#include<bits/stdc++.h>
using namespace std;
int n,t,a[100001],ans,b[100001],c[100001];
map<int,int> p;
priority_queue <int,vector<int>,less<int> > q;//从大到小 
//priority_queue <int,vector<int>,greater<int> > q1;//从小到大 
int main(){
    
    
	cin>>n;
	for(int i=1;i<=n;i++){
    
    //输入 
		cin>>a[i];
	}
	for(int i=1;i<=n;i++){
    
    //先将a[1]+b[1...n]放入队列 
		cin>>b[i];
		q.push(a[1]+b[i]);
	}
	for(int i=2;i<=n;i++){
    
    //枚举 
		for(int j=1;j<=n;j++){
    
    
			if(a[i]+b[j]>q.top()) break;
			//由于b是一个有序表,所以如果当前这个都大了那么后面的会更大 ,所以可以直接break 
			q.pop();//弹出最大的 
			q.push(a[i]+b[j]);//放入新的数 
		}
	}
	//这时得到了一个大顶堆,我不知道怎样倒过来,所以用了最笨的方法,如果有更好的方法欢迎评论区讨论哦
	int i=0;
	while(!q.empty()){
    
    //倒过来
		i++;
		c[i]=q.top();
		q.pop();
	}
	for(int j=i;j>=1;j--) cout<<c[j]<<" ";//输出
	return 0;
}

This question is over like this, remember to support it three times in a row QAQ

Guess you like

Origin blog.csdn.net/m0_61360607/article/details/132168300