K Smallest Sums (数据结构)UVA - 11997

K Smallest Sums(排序)


You’re given k arrays, each array has k integers. There are k
k 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).
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
Sample Output
9 10 12
2 2
题意:有k个数组每个数组有k个数,取每个数组中的一个数相加,在加得的数中输出最小的k个数


题解:sort对每个数组进行排序,取前两个数组相加,求得最小的k个数记录下来,再将这k个数与下一个数组相加。数组两两相加时用优先队列,使得复杂度为O(n)(若不考虑优先队列)。


#include<bits/stdc++.h>
#define ll long long
#define MT(a,b) memset(a,0,sizeof(a));
using namespace std;
const int maxn=1e3+5;
int n;
struct dd
{
    int v,id;
    dd (){}
    dd (int v,int id):v(v),id(id){}
    bool operator<(const dd &a)const
    {
        return a.v<v;
    }
};
int a[maxn][maxn];
int main()
{
    while(cin>>n)
    {
        MT(a,0);
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                cin>>a[i][j];
        sort(a[0],a[0]+n);
        for(int i=0;i<n-1;i++)
        {
            priority_queue<dd>Q;
            sort(a[i+1],a[i+1]+n);
            for(int j=0;j<n;j++) Q.push(dd(a[i+1][0]+a[0][j],0));//该数组的每个数加上下一个数组的第一个数,将之压入优先队列
            for(int j=0;j<n;j++)
            {
                dd t=Q.top();
                Q.pop();
                a[0][j]=t.v;//每次记录优先队列的最小数,并将之推出
                t.v=t.v-a[i+1][t.id]+a[i+1][t.id+1];//t.v为两个数之和,现在减去后面的那个数(即下一个数组的数),再加上下一个数组后面的数(此时得到的是另一个数,该数为两个数组分别取一个数的和)
                t.id++;//id加一
                if(t.id<n) Q.push(t);//将之压入优先队列
            }
        }
        for(int j=0;j<n-1;j++)cout<<a[0][j]<<" ";
        cout<<a[0][n-1]<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Mannix_Y/article/details/80216001