簡練一哈問題就是:給兩個長度為 N N 的數組 a a 和 b b ,求那麼 a[i]+b[i] a [ i ] + b [ i ] 有 N2 N 2 種組合,求最小的前 N N 個組合
比如 N=4 N = 4
a:1,2,3,4 a : 1 , 2 , 3 , 4
b:5,6,7,8 b : 5 , 6 , 7 , 8
前 N N 個最小的就是 6,7,7,8 6 , 7 , 7 , 8
數組都先排序哈
我們先弄個初始答案:什麼叫初始答案喃。
比如 a a 裡面的每個數 a[i] a [ i ] 都加上 b b 數組裡面最小的 b[1] b [ 1 ] ,是不是差不多就是最小的 N N 個數了
這 N N 個數就是 6,7,8,9 6 , 7 , 8 , 9 對吧
但是這裡面還有點問題
最小的數是6沒問題,但是第二小的數有兩種組合都是: a[2]+b[1] a [ 2 ] + b [ 1 ] 和 a[1]+b[2] a [ 1 ] + b [ 2 ] ,那麼這個 a[1]+b[2] a [ 1 ] + b [ 2 ] 應該作為第三小才對,而這個第三小卻沒有算到,怎麼辦喃。
我們將我們的初始答案先弄到優先隊列裡面去,小的在隊首,隊首的就是最小的組合,而且這個最小的要用來最佳化,比如當前最小的是 a[1]+b[1] a [ 1 ] + b [ 1 ] ,那麼把 b[1] b [ 1 ] 用 b[2] b [ 2 ] 換掉,也是比較小的組合,那就把這種組合加進隊列,與其他的比較,反正每次最小的都是隊首的~
/*給兩個長度為N的數組a和b,求那麼a[i]+b[i]有N^2種組合,求最小的前N個組合*/#include"iostream"#include"algorithm"#include"queue"using namespace std;const int maxn=1e6+5;int a[maxn],b[maxn],c[maxn];int N;struct AAA{ int v,id; AAA (){} AAA (int v,int id):v(v),id(id){} bool operator<(const AAA &a)const { return a.v<v; }};int main(){ while(cin>>N) { priority_queue<AAA>que; for(int i=1;i<=N;i++)cin>>a[i]; for(int i=1;i<=N;i++)cin>>b[i]; sort(a+1,a+1+N); sort(b+1,b+1+N); for(int i=1;i<=N;i++)que.push(AAA(b[1]+a[i],1)); for(int i=1;i<=N;i++) { AAA t=que.top(); que.pop(); c[i]=t.v; t.v=t.v-b[t.id]+b[t.id+1]; t.id++; que.push(t); } for(int i=1;i<=N;i++)cout<<c[i]<<" "; cout<<endl; }}
而這道題就是重複幾次這樣的操作就完了
#include"iostream"#include"cstdio"#include"algorithm"#include"queue"using namespace std;const int maxn=750+5;long long a[maxn],b[maxn];long long N;struct AAA{ long long v,id; AAA (){} AAA (long long v,long long id):v(v),id(id){} bool operator<(const AAA &a)const { return a.v<v; }};int f(){ priority_queue<AAA>que; for(int i=1;i<=N;i++) { que.push(AAA(b[1]+a[i],1)); } for(int i=1;i<=N;i++) { AAA t=que.top(); que.pop(); a[i]=t.v; t.v=t.v-b[t.id]+b[t.id+1]; t.id++; que.push(t); }}int main(){ while(cin>>N) { int T=N-1; for(int i=1;i<=N;i++)cin>>a[i]; sort(a+1,a+1+N); while(T--) { for(int i=1;i<=N;i++)cin>>b[i]; sort(b+1,b+1+N); f(); } for(int i=1;i<N;i++)cout<<a[i]<<" "; cout<<a[N]<<endl; }}