思路
- 先把temp1[1]与temp2数组中的各个元素和组成一个大小为n的大根堆。
- 继续插入temp1和temp2数组的其他元素和的组合,如果和小于堆顶(最大值),替换堆顶并调整,最终就保证了n个最小的元素。
- 对这个堆进行堆排序,输出。
反思
- 错误思路:把整个数的和放入堆,会数组越界。
- 学会这种对堆的维护,挑选所选的数据。不一定要全部数据都并入堆
- 必须选择大根堆,不然无法挑选小值,提示有点问题。
- 为了节省时间,因为数组是递增的,所有可以进行判断temp1[i]+temp2[j]<=heap[1],不满足就要break掉。
代码
#include<algorithm>
using namespace std;
const int maxn1=100001;
int heap[100001];
int n;
int count1=0;
int temp1[maxn1],temp2[maxn1];
void downAdujust(int low,int high){ //向下调整
int i=low,j=2*low;
while(j<=high){
if(j+1<=high&&heap[j+1]>heap[j]) j++;
if(heap[i]>=heap[j]) break;
swap(heap[i],heap[j]);
i=j;
j=2*i;
}
}
void createHeap(){ //建堆
for(int i=n/2;i>0;i--){
downAdujust(i,n);
}
}
void heapSort(){ //堆排序
for(int i=n;i>0;i--){
swap(heap[1],heap[i]);
downAdujust(1,i-1);
}
}
int main(){
while(scanf("%d",&n)!=EOF){
count1=0;
for(int i=1;i<=n;i++){
scanf("%d",&temp1[i]);
}
for(int i=1;i<=n;i++){
scanf("%d",&temp2[i]);
heap[i]=temp1[1]+temp2[i];
}
createHeap();
for(int i=2;i<=n;i++){
for(int j=1;j<=n;j++){
if(temp1[i]+temp2[j]<=heap[1]){ //进行新数和堆顶的比较
heap[1]=temp1[i]+temp2[j];
downAdujust(1,n);
}
else break;
}
}
heapSort();
for(int i=1;i<=n;i++) printf("%d ",heap[i]);
printf("\n");
}
return 0;
}