【POJ2442】Sequence 解题报告+代码

 
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
//#define INPUT
using namespace std;
/**
    Problem:POJ2442 - Sequence
    Begin Time : 2nd/March/2012 1:00 p.m.
    End Time: 2nd/March/2012 4:14 p.m
    Cost Time: 3H 14Min
    看的别人的解题报告过的,非常感谢
    http://hi.baidu.com/%C0%B6%C9%ABarch/blog/item/f9d343f49cd92e53d7887d73.html
    的博主!
    思路:
    我们要找到n个smallest的数,用贪心法可以解决这一问题。
    (1)维护两个数组,a和b,以及一个大根堆p
        循环不变式:
        (1)初始化
            将元素读入a,将a排序(从小到大)
            执行并重复(2)
        (2)保持
            对于这全部数据第二行到第m行(从第二行开始,因为第一行读到a里了)
            将元素读入b,将b排序(从小到大)
            For i = 0 to n -1
                heap.push(a[i]+b[0]);
            然后
            for(int i = 1; i < n;i++)
            {
                for(int j = 0 ; j < n; j++)
                {
                    if( (b[i] + a[j]) > heap.top() ) break;
                    heap.pop(); ///从heap中删除一个最大的元素,从而保证heap中元素数目不变
                    heap.push(b[i] + a[j]);
                }
            }
            /////这样,就选出了n个最小值
            然后把heap中的n个值按照从小到大给
            a[1] -> a[n],并将heap清空。
            执行(2)
        (3)最终结果
            输出a中全部元素就可以了,注意,对于每个case都要换行哦!
*/
bool comp(int a,int b)
{
    return b > a;
}
int main(int argc,char* argv[])
{
#ifdef INPUT
    freopen("b:\\acm\\poj2442\\input.txt","r",stdin);
#endif
    int T;
    scanf("%d",&T);
    for(int i = 0 ; i < T; i++)
    {
        int m = 0 , n = 0;
        vector<int> a;vector<int> b;
        priority_queue<int> h_heap;
        a.clear();b.clear();

        int buf = 0;
        scanf("%d%d",&m,&n);
        for(int j = 0 ; j < n; j++)
        {
            scanf("%d",&buf);
            a.push_back(buf);
        }
        sort(&a[0],&a[0]+n,comp);
    for(int z = 0 ; z < m - 1; z++)
    {
        b.clear();
       for(int j = 0 ; j < n; j++)
        {
            scanf("%d",&buf);
            b.push_back(buf);
        }
        sort(&b[0],&b[0]+n,comp);
        for(int j = 0; j < n; j++)
        {
            h_heap.push(a[j]+b[0]);
        }
        ///这时候b已经选过了;
        for(int j = 1; j < n; j++)
        {
            for(int k = 0 ; k < n ; k++)
            {
                if ( b[j] + a[k] > h_heap.top() )
                {
                    break;
                }
                else
                {
                    h_heap.pop();
                    h_heap.push(b[j]+a[k]);
                }
            }
        }
        //////这时候已经选出来该两行的n个最小值了
        for(int j = 0; j < n; j++)
        {
            a[ n - 1 - j ] = h_heap.top();
            h_heap.pop();
        }
        //////copy回去,把a
    }
        for(int j = 0 ; j < n; j++)
        {
            printf("%d ",a[j]);
        }
        printf("\n");
    }
    return 0;
}

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章