POJ 2442 -- Squence(堆)

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


题目大意:

  给你n*m的矩阵,然后每行取一个元素,组成一个包含n个元素的序列,一共有n^m种序列,

让你求出序列和最小的前n个序列的序列和。

 

解题步骤:

1.将第一序列读入data1向量中,并按升序排序。

2.将数据读入data2向量中,并按升序排序。

    将data2[0] + data1[i] ( 0<=i<=n-1)读入dataq向量中

    用make_heap对dataq建堆。

    然后data2[1] + data1[i] (0<=i<=n-1),如果data2[1] + data1[i]比堆dataq的顶点大,则退出,否则删除

    堆的顶点,插入data2[1] + data1[i]。然后是data2[2],...data2[n - 1]

 3.将dataq的数据拷贝到data1中,并对data1按升序排序

 4.循环2,3步,直到所有数据读入完毕。

 5.打印data1中的数据即为结果。

 

AC代码如下

1.heap

 1 #include<cstdio>
2 #include<algorithm>
3 #include<iostream>
4 #define Max 2008
5 using namespace std;
6 int sum[Max],data[Max],Q[Max];
7 int main()
8 {
9 int i,j,k,t,m,n,temp;
10 scanf("%d",&t);
11 while(t--)
12 {
13 memset(sum,0,sizeof(sum));
14 scanf("%d %d",&m,&n);
15 for(i=0;i<n;i++)
16 scanf("%d",&sum[i]);
17 for(i=1;i<m;i++)
18 {
19 memset(data,0,sizeof(data));
20 sort(sum,sum+n);
21 for(j=0;j<n;j++)
22 scanf("%d",&data[j]);
23 sort(data,data+n);
24 for(j=0;j<n;j++)
25 Q[j]=sum[0]+data[j];
26 make_heap(Q,Q+n);
27 for(j=1;j<n;j++)
28 {
29 for(k=0;k<n;k++)
30 {
31 temp=sum[j]+data[k];
32 if(temp>=Q[0])
33 break;
34 pop_heap(Q,Q+n);
35 Q[n-1]=temp;
36 push_heap(Q,Q+n);
37 }
38 }
39 for(j=0;j<n;j++)
40 sum[j]=Q[j];
41 }
42 sort(sum,sum+n);
43 for(j=0;j<n-1;j++)
44 printf("%d ",sum[j]);
45 printf("%d\n",sum[n-1]);
46 }return 0;
47 }



2.heap+vector

 1 #include<cstdio>
2 #include<iostream>
3 #include<vector>
4 #include<algorithm>
5 using namespace std;
6 bool cmp(int a,int b)
7 {
8 return a < b;
9 }
10 int main()
11 {
12 int T,m,n,i,j,k,temp,ans=0;
13 vector<int>data1,data2,dataQ;
14 cin>>T;
15 while(T--)
16 {
17 data1.clear();
18 cin>>m>>n;
19 for(i=0;i<n;i++)
20 {
21 cin>>temp;
22 data1.push_back(temp);
23 }
24 for(i=1;i<m;i++)
25 {
26 sort(data1.begin(),data1.end(),cmp);
27 data2.clear();
28 dataQ.clear();
29 for(j=0;j<n;j++)
30 {
31 cin>>temp;
32 data2.push_back(temp);
33 }
34 sort(data2.begin(),data2.end(),cmp);
35 for(j=0;j<n;j++)
36 dataQ.push_back(data1[j]+data2[0]);
37 make_heap(dataQ.begin(),dataQ.end(),cmp);
38 for(j=1;j<n;j++)
39 {
40 for(k=0;k<n;k++)
41 {
42 temp=data1[k]+data2[j];
43 if(temp>=dataQ[0])
44 break;
45 pop_heap(dataQ.begin(),dataQ.end(),cmp);
46 dataQ.pop_back();
47 dataQ.push_back(temp);
48 push_heap(dataQ.begin(),dataQ.end(),cmp);
49 }
50 }copy(dataQ.begin(),dataQ.end(),data1.begin());
51 }
52 sort(data1.begin(),data1.end(),cmp);
53 for(i=0;i<n-1;i++)
54 printf("%d ",data1[i]);
55 printf("%d\n",data1[n-1]);
56 }return 0;
57 }


PS:

  这道题,刚开始没有思路,想的方法就是暴力枚举,但考虑到n^m的范围有点大,就放弃了,然后在网上看到别人的解题报告,

才有所顿悟。这也是我第一次用STL中的vector和heep,遂纪念一下。


posted @ 2012-02-15 18:41  Chnwy  阅读(2147)  评论(0编辑  收藏  举报