#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;
}
【POJ2442】Sequence 解題報告+代碼
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.