【暑假】[实用数据结构]UVa11997 K Smallest Sums

来源:互联网 发布:淘宝客域名注册 编辑:程序博客网 时间:2024/06/06 04:27
UVa11997 K Smallest Sums

 题目:

                                                        K Smallest Sums

 

You're given k arrays, each array has k integers. There are kk ways to pick exactly one element in each array and calculate the sum of the integers. Your task is to find the k smallest sums among them.

 

Input

 

There will be several test cases. The first line of each case contains an integer k (2<=k<=750). Each of the following k lines contains k positive integers in each array. Each of these integers does not exceed 1,000,000. The input is terminated by end-of-file (EOF). The size of input file does not exceed 5MB.

 

Output

 

For each test case, print the k smallest sums, in ascending order.

 

Sample Input

 

31 8 59 2 510 7 621 11 2

 

Output for the Sample Input

 

9 10 122 2

------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

思路:

 先思考2个有序表(sort后)AB合成的情况。组织如下

【 表】1: A1+B1 <=  A1+B2 <=  A1+B3 <=......

 【表】2:A2+B1 <=  A2+B2 <=  A2+B3 <=......

 ......

 【表】n:An+B1 <=  An+B2 <=  An+B3 <=......

转化为多路归并问题且有总数限制为k,因此将n个【表】合并为一个有序【表】C且表中数据数目为k。优先队列处理:初始化优先队列为n个表的第一元素,每次在队列中取出最小元素加入C并将该最小元素在【表】中的后一个元素入队。共取k个元素。

对于k个有序表的情况:两两合并。

 

于是有代码如下:

 

 1 #include<cstdio> 2 #include<algorithm> 3 #include<queue> 4 #define FOR(a,b,c) for(int a=(b);a<(c);a++) 5 using namespace std; 6  7 const int maxn = 800 + 10; 8  9 struct Node{10     int s,b;11     bool operator <(const Node& rhs) const{ //相反定义 < 12       return s>rhs.s; 13     }14 };15 16 17 void merge(int* A,int* B,int*C,int n){ //合并AB数组取其前n小的和放入C 18 priority_queue<Node> Q;19   FOR(i,0,n) Q.push(Node{A[i]+B[0],0});20   FOR(i,0,n){21       Node u=Q.top();Q.pop();22       C[i]=u.s;23       int b=u.b;24       if(b+1 < n) Q.push(Node{u.s-B[b]+B[b+1],b+1}); //加入A[a][b+1] 25   }    26 }27 28 int main(){29 int n;30 int A[maxn],B[maxn];31 32   while(scanf("%d",&n)==1){33       FOR(j,0,n) scanf("%d",&A[j]); sort(A,A+n);34       FOR(i,1,n){35            FOR(j,0,n) scanf("%d",&B[j]);36            sort(B,B+n);37          merge(A,B,A,n);38     }39     printf("%d",A[0]); 40     FOR(i,1,n)41       printf(" %d",A[i]);42     printf("\n");43  }44  return 0;45 }

 

0 0
原创粉丝点击