Uva11997 K Smallest Sums

来源:互联网 发布:王奕霏编程 编辑:程序博客网 时间:2024/06/05 07:00

题目: 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).
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
【多路归并问题】
要用优先队列logk
k个序列,k个数,两两归并
时间复杂度O(k^2*logk)

#include<iostream>#include<cstdio>#include<ctime>#include<algorithm>#include<queue>using namespace std;const int N=760;int n,A[N],B[N];inline int readin(){    int res = 0;    char ch;    while((ch = getchar())>'9'||ch <'0');    res= ch-'0';    while((ch = getchar())>='0'&&ch <='9')        res= res* 10+ch -'0';    return res;}struct ii{    int s,b;    ii(int s = 0,int b =0):s(s),b(b){ }    bool operator <(const ii &a)const {        if(s^a.s)return s>a.s;    }};//a[1]+b[1]<a[1]+b[2]……,b 有序的,s=a[i]+b[j] ->s'=s-b[j]+b[j+1],只需要存储s,bvoid merge(){//two merge    priority_queue<ii>q;    for(int i = 1; i<= n;i++)        q.push(ii(A[i]+B[1],1));    for(int i = 1; i<= n;i++)//push n min into C[N]    {        ii tmp=q.top();        q.pop();        A[i]=tmp.s;        int b =tmp.b;        if(b+1<=n)q.push(ii(tmp.s-B[b]+B[b+1],b+1));//贪心的思维,,取当前最小的下一个    }//最多n-1次,所以如果一直在一个序列,最多可能有一次会多余}int main(){    freopen("Uva.in","r",stdin);    freopen("Uva.out","w",stdout);    while((scanf("%d",&n)==1)&&n){            for(int i = 1; i<= n;i++)            A[i]=readin();            sort(A+1,A+n+1);            for(int o=2; o <= n; o++){                for(int i = 1; i<= n;i++)                B[i]=readin();                sort(B+1,B+n+1);                merge();//指针传值再到A数组            }            printf("%d",A[1]);            for(int i = 2; i<= n;i++)            printf(" %d",A[i]);            printf("\n");    }    return 0;}
0 0