https://www.luogu.org/blogAdmin/article/list?pageType=list[神奇鏈接嚶嚶嚶](https://www.luogu.org/problemnew/show/P1631)
這兩天瘋狂刷二叉堆的題目哈,可是頭緒仍是不夠明朗嚶嚶嚶 ,基本就是必需要粗略看一下別人的思路,而後才能漸漸本身作出來。。。
那分析一下這道題,由於數據過大,so暴力枚舉拿滿分確定是不現實的,那既然用堆,固然也不能把全部狀況算出來在入堆,那跟暴力豈不是沒區別??因此咱們須要分析一下這道題
首先,排序我就不說了(正常看到無序數組想到排序仍是很正常的),那麼以後呢,就是對兩個數組進行分析
那麼既然a數組排過序了,很顯然,最小值必定是(a[1]+b[1],a[1]+b[2],a[1]+b[3]......a[1]+b[n])中的一個,由於a[1]是a數組中最小的一個,而b數組中最小的一個也一定在b[1]到b[n]中,因此以上n個數中必定會出現最小值,咱們定義一個結構體小根堆,將b[i]對應相加的a[j]的j以及a[j]+b[i]的值記錄在小根堆中,每輸出一個,就將記錄下標爲i的b數組對應的a數組的下標++,以此類推,輸出n個以後結束
實際上,這仍是很好實現的嚶嚶嚶~~~node
#include<cstdio> #include<algorithm> #include<cmath> #include<queue> #include<cstring> #include<iostream> using namespace std; int n; int z[100005],y[100005],zy[100005]; struct node{ int k,l,ans; }; priority_queue < node,vector<node>,greater<node> > q; bool operator >(const node &a,const node &b){ return a.ans>b.ans; } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",z+i); zy[i]=1; } sort(z+1,z+1+n); for(int i=1;i<=n;i++){ scanf("%d",y+i); q.push((node){i,zy[i],z[i]+y[zy[i]]}); } while(n--){ printf("%d ",q.top().ans); int w=q.top().k; zy[w]++; q.pop(); q.push((node){w,zy[w],z[w]+y[zy[w]]}); } return 0; }
emmmm
不要問我爲何變量名總是用z和y(我纔不會告訴你zy是一我的名字的縮寫呢)ios