題解——UVA11997 K Smallest Sums
阿新 • • 發佈:2018-08-16
clas 題解 smallest [] 下標 src spa con png
題面
背景
輸入
輸出
翻譯(渣自翻)
給定K個包含K個數字的表,要求將其能產生的\( k^{k} \)個值中最小的K個輸出出來
題解
k路歸並問題的經典問題
可以轉化為二路歸並問題求解
考慮A[],B[]兩個有序數組
使用堆,記錄一些二元組\( (x,y) \),x表示值,y表示對應的b的下標,因為我們是把b合並到a上,所以我們能夠根據記錄的下標推出後面的值
然後兩兩合並
所以就很簡單
放代碼
#include <cstdio> #include <algorithm> #include <queue> usingnamespace std; struct asshole{ int w,t; bool operator < (const asshole b) const{ return w>b.w; } }; priority_queue<asshole> q; int kz[10000],kk[10000]; int n; void merge(int *a,int *b,int *c){ while(!q.empty()) q.pop(); for(int i=1;i<=n;i++) q.push((asshole){a[i]+b[1],1}); for(int i=1;i<=n;i++){ asshole in = q.top(); q.pop(); a[i]=in.w; int pos=in.t; if(pos+1<=n) q.push((asshole){in.w-b[pos]+b[pos+1],pos+1}); } } int main(){ while(scanf("%d",&n)==1){ for(int i=1;i<=n;i++) scanf("%d",&kz[i]); sort(kz+1,kz+n+1); for(int j=1;j<=n-1;j++){ for(int i=1;i<=n;i++) scanf("%d",&kk[i]); sort(kk+1,kk+n+1); merge(kz,kk,kz); } for(int i=1;i<=n-1;i++) printf("%d ",kz[i]); printf("%d",kz[n]); printf("\n"); } }
題解——UVA11997 K Smallest Sums