<span style="font-family: Arial, Helvetica, sans-serif;">// #pragma comment(linker, "/STACK:1024000000,1024000000")</span>
/* 题意:有K个整数数组,包含K个元素。在每个数组中取一个元素加起来,可以得到k^k个和。 求这些和中最小的K个值 分析:这题有简化版本的,即2个整数数组A,B,包含K个元素,在每个数组中取一个元素加起 来,可以得到k^2个和,求这些和中最小的K个值。我们需要把这k^2个和组织成如下k个有序表. 表1:A1+B1<=A1+B2<=......<=A1+Bk 表2: A2+B1<=A2+B2<=......<=A2+Bk 表k:Ak+B1<=AK+B2<=......<=Ak+Bk 我们可以用二元组(s,b)来表示一个元素即s=Aa+Bb;为什么不保存A的下标a呢?因为我们用 不到a的值。如果我们需要元素(s,b)在表a的下一个元素(s',b+1). 只需要计算s'=s+B[b+1]-B[b]; 这样我们先将K个表的第一个元素压入优先队列,这样队列中就用k个元素了。然后从队列中出 一个值,就压入这个值所在表的下一个元素,直到k个值都出了优先队列。 这样就得到k个最小值了。。 然后对与K个数组。我们只需两两合并即可。 */ #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <limits.h> // #define DEBUG #ifdef DEBUG #define debug(...) printf( __VA_ARGS__ ) #else #define debug(...) #endif #define MEM(x,y) memset(x, y,sizeof x) using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; int G[760][760]; struct Item{ int s, b; Item(int s,int b){ this->s = s; this->b = b; } bool operator < (const Item& rhs)const{ return this->s > rhs.s; } }; int k; int res[760]; void merge(int* A,int* B,int *C){ int cnt = 0; priority_queue<Item> que; for (int i = 0;i < k;i++) que.push(Item(A[i] + B[0],0)); while(!que.empty()){ Item tmp = que.top(); que.pop(); C[cnt++] = tmp.s; if (tmp.b + 1 < k) que.push(Item(tmp.s + (B[tmp.b+1] - B[tmp.b]),tmp.b+1)); if (cnt == k) break; } } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); while(~scanf("%d",&k)){ for (int i = 0;i < k;i++){ for (int j = 0;j < k;j++) scanf("%d",&G[i][j]); sort(G[i],G[i]+k); } memcpy(res,G[0],sizeof res); for (int i = 1;i < k;i++){ merge(res,G[i],res); // for (int i = 0;i < k;i++) // printf("%d ",res[i]); // printf("\n"); } for (int i = 0;i < k;i++){ if (i == 0) printf("%d",res[i]); else printf(" %d",res[i]); } puts(""); } return 0; }