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("\n");
59         //memset(sh,0,sizeof(sh));
60     }
61     return 0 ;
62 }
View Code

 

posted on 2013-08-20 21:09  枫、  阅读(203)  评论(0编辑  收藏  举报