POJ 2442 Sequence (堆+K路归并)

题目:http://poj.org/problem?id=2442

 

思路:优先队列(堆)+K路归并

//开始之前先说个例题:

例题一:

 
 
 
例题二:(例题一的应用)
 
有了前面2个例题,思路就基本清晰了,然后就是要明白,m个有序表的前n个最小和可由m-1个有序表的qian那个最小和与第m个有序表形成。以此类推,其实就是例二的扩展算法。
 
开始忘记给他们排序、WA了一次。。。。。。
 
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <iomanip> #include <climits> #include <vector> #include <stack> #include <queue> #include <set> #include <map> #include <algorithm> #include <string> #include <cstring>



using namespace std; const double EPS = 1e-11; void Swap(int &a,int &b){   int t=a;a=b;b=t; } int Max(int a,int b)    {   return a>b?a:b; } int Min(int a,int b)    {   return a<b?a:b; } int a[2005],b[2005]; int n,m; struct node { int a,b; int key; friend bool operator < (node n1 ,node n2)      //priority_queue需要的cmp函数 { return n2.key<n1.key; } }; void fuck()                    //K路归并求两个序列和过程 { node t; priority_queue < node , vector< node > > Q; for (int i=0;i<n;i++) { t.a=i;                  //t.a表示这个最值来自哪个表:a[i]+b[0],a[i]+b[1],...,a[i]+b[n] t.b=0;                  //t.b表示当前表已经选到了a[i]+b[t.b](刚开始第一个是0) t.key=a[i]+b[0]; Q.push(t); } int c[2005]; int k=0; while(k!=n) { t=Q.top(); Q.pop(); c[k++]=t.key;              //把最小值放入新序列中 t.b++;                  //此表向后推一个 t.key=a[t.a]+b[t.b];           Q.push(t);                //把当前表的新元素重新加入到堆中  } for (int i=0;i<n;i++) a[i]=c[i]; return ; } int main() { int t; scanf("%d",&t); while(t--) { cin>>m>>n; for (int i=0;i<n;i++) scanf("%d",&a[i]); sort(a,a+n); for (int i=0;i<m-1;i++) { for (int j=0;j<n;j++) scanf("%d",&b[j]); sort(b,b+n); fuck(); } printf("%d",a[0]); if (n>1) for (int i=1;i<n;i++) printf(" %d",a[i]); printf("\n"); } return 0; }

 

你可能感兴趣的:(sequence)