zoukankan      html  css  js  c++  java
  • 【暑假】[实用数据结构]UVa11997 K Smallest Sums

    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

    3
    1 8 5
    9 2 5
    10 7 6
    2
    1 1
    1 2
    

    Output for the Sample Input

    9 10 12
    2 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("
    ");
    43  }
    44  return 0;
    45 }
  • 相关阅读:
    数据库三大范式讲解
    transition、-moz-transition、-webkit-transition、-o-transition是什么意思?怎样用?
    js常用函数
    margin()与offset()的区别
    小总结 小理解 (不咋全面...)
    栈的C++实现(指针)——创建-push-pop-top-清空栈-处理栈
    链表的C++实现——创建-插入-删除-输出-清空
    运行时间中的对数
    最大子序列和
    mapminmax的用法详解 _MATLAB
  • 原文地址:https://www.cnblogs.com/lidaxin/p/4710370.html
Copyright © 2011-2022 走看看