• UVa 11997 (优先队列 多路归并) K Smallest Sums


    考虑一个简单的问题,两个长度为n的有序数组A和B,从每个数组中各选出一个数相加,共n2中情况,求最小的n个数。

    将这n2个数拆成n个有序表:

    A1+B1≤A1+B2≤...

    A2+B1≤A2+B2≤...

    ...

    An+B1≤An+B2≤...

    然后用优先队列合并成一个有序表即可。队列中需要记录两个数的和s,以及在B中的下标b,

    比如Aa+Bb出队以后,应该将Aa+B(b+1) = Aa + Bb - Bb + Bb+1 = s - Bb + bb+1入队

    对于书上最后的一个思考问题,merge函数中对A[0]又读又写,会不会出错。答案当然是不会的,因为进入到函数内部你会发现,对A数组其实是先读后写的。

     1 #include <cstdio>
     2 #include <queue>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 const int maxn = 750 + 10;
     7 int a[2][maxn];
     8 
     9 void scan(int& x)
    10 {
    11     char c;
    12     while(c = getchar(), c < '0' || c > '9');
    13     x = c - '0';
    14     while(c = getchar(), c >= '0' && c <= '9') x = x*10 + c - '0';
    15 }
    16 
    17 struct Node
    18 {
    19     int sum, b;
    20     Node(int s, int b):sum(s), b(b) {}
    21     bool operator < (const Node& rhs) const
    22     { return sum > rhs.sum; }
    23 };
    24 
    25 void merge(int n, int* A, int* B, int* C)
    26 {
    27     priority_queue<Node> Q;
    28     for(int i = 0; i < n; i++) Q.push(Node(A[i]+B[0], 0));
    29 
    30     for(int i = 0; i < n; i++)
    31     {
    32         Node t = Q.top(); Q.pop();
    33         int b = t.b, sum = t.sum;
    34         C[i] = sum;
    35         if(b + 1 < n) Q.push(Node(sum-B[b]+B[b+1], b+1));
    36     }
    37 }
    38 
    39 int main()
    40 {
    41     //freopen("in.txt", "r", stdin);
    42 
    43     int k;
    44     while(scanf("%d", &k) == 1)
    45     {
    46         for(int i = 0; i < k; i++) scan(a[0][i]);
    47         sort(a[0], a[0] + k);
    48         for(int i = 1; i < k; i++)
    49         {
    50             for(int j = 0; j < k; j++) scan(a[1][j]);
    51             sort(a[1], a[1] + k);
    52             merge(k, a[0], a[1], a[0]);
    53         }
    54 
    55         for(int i = 0; i < k; i++)
    56         {
    57             if(i) printf(" ");
    58             printf("%d", a[0][i]);
    59         }
    60         puts("");
    61     }
    62 
    63     return 0;
    64 }
    代码君
  • 相关阅读:
    二叉树——Java实现
    Java实现单链表的增删查改及逆置打印
    常见排序——Java实现
    [导入]Interesting Finds: 2007.12.10
    [导入]Interesting Finds: 2007.12.09
    [导入]Interesting Finds: 2007.12.12
    [导入]Interesting Finds: 2007.12.06
    [导入]Interesting Finds: 2007.12.07
    [导入]Interesting Finds: 2007.12.04
    [导入]Interesting Finds: 2007.12.05
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4341882.html
Copyright © 2020-2023  润新知