http://poj.org/problem?id=2442
题意 :就是输入m个数集,每个含n个数,求从每个集合取一个数后,按非降序输出前n小的和。
思路 : 本来打算是用几个for循环的,后来觉得要是真这么简单就不会在堆里分类了,所以,经过会神详细指导讲解,略懂略懂,弄俩优先队列,正好搞定
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<vector> 5 #include<iostream> 6 using namespace std ; 7 const int maxn = 2005 ; 8 int main() 9 { 10 int n ; 11 scanf("%d",&n); 12 int m,t,s; 13 int a[maxn] ; 14 for(int i = 1 ; i <= n ; i++) 15 { 16 priority_queue<int ,vector<int>,less<int> > Q;//大根堆是用来找和最小的值的 17 priority_queue<int ,vector<int>,greater<int> > P;//小根堆是将输入的每行数从小到大排序 18 scanf("%d %d",&m,&t); 19 for(int h = 0 ; h < t ; h++) 20 { 21 scanf("%d",&s);//先输入第一行 22 P.push(s); 23 } 24 for(int h = 1 ; h < m ; h++) 25 { 26 for(int j = 0 ; j < t ; j++) 27 scanf("%d",&a[j]) ; 28 while(!P.empty()) 29 { 30 int b = P.top(); 31 P.pop(); 32 for(int j = 0 ; j < t ; j++) 33 { 34 if(Q.size() == t && b+a[j] < Q.top()) 35 { 36 //如果大根堆里已经有了t个数了,那就判断首元素与b+a[j]谁大,若是大,就删掉,加入新的 37 Q.pop(); 38 Q.push(b+a[j]); 39 } 40 else if(Q.size() < t) 41 Q.push(b+a[j]) ; 42 } 43 } 44 45 while(!Q.empty()) 46 { 47 P.push(Q.top()); 48 Q.pop(); 49 } 50 } 51 printf("%d",P.top()) ; 52 P.pop(); 53 for(int k = 1 ; k < t ; k++) 54 { 55 printf(" %d",P.top()) ; 56 P.pop(); 57 } 58 printf(" "); 59 //memset(sh,0,sizeof(sh)); 60 } 61 return 0 ; 62 }