UVA - 11997(巧妙的优先队列)

题意:

  有k个整数数组,各包含k个元素,在每个数组中取一个元素加起来,可以得到kk个和,求这些和中最小的k个值

解析:

  从简单的情况开始分析:经典方法,对原题没有思路,那么分析问题的简化版

UVA - 11997(巧妙的优先队列)_第1张图片

这是对于两个。。。而对于k个 我们只需要两两处理合并出新数组 然后再与另一个数组合并处理。。依次推理

#include 
#include 
#include 
#include 
#include 
#include <set>
#include 
#include 
#include 
#include 
#include 
#define rap(i, a, n) for(int i=a; i<=n; i++)
#define MOD 2018
#define LL long long
#define ULL unsigned long long
#define Pair pair
#define mem(a, b) memset(a, b, sizeof(a))
#define _  ios_base::sync_with_stdio(0),cin.tie(0)
//freopen("1.txt", "r", stdin);
using namespace std;
const int maxn = 1010, INF = 0x7fffffff;
int A[maxn][maxn];

struct node
{
    int s, b;
    node(int s, int b):s(s), b(b){}
    bool operator < (const node& a) const {
        return s > a.s;
    }
};

void mer(int* A, int* B, int* C, int n)
{
    priority_queue q;
    rap(i, 1, n)
        q.push(node(A[i]+B[1], 1));
    rap(i, 1, n)
    {
        node e = q.top(); q.pop();
        C[i] = e.s;
        int b = e.b;
        if(b + 1 <= n)
        {
            e.s = e.s - B[b] + B[b+1];
            q.push(node(e.s, b+1));
        }
    }
}

int main()
{
    int n;
    while(cin>> n)
    {
        rap(i, 1, n)
        {
            rap(j, 1, n)
                cin>> A[i][j];
            sort(A[i]+1, A[i]+n+1);
        }
        rap(i, 2, n)    //两两合并
         mer(A[1], A[i], A[1], n);
        rap(i, 1, n)
        {
            if(i != 1)
                cout<< " ";
            cout<< A[1][i];
        }
        cout<< endl;
    }

    return 0;
}

 

转载于:https://www.cnblogs.com/WTSRUVF/p/9437726.html

你可能感兴趣的:(UVA - 11997(巧妙的优先队列))