您的位置:首页 > 其它

单调队列

2011-06-17 21:46 381 查看
单调队列 : 队列中保存的是潜在的解,队首保存最优解。
支持操作 : 与普通队列支持的操作相同,push_back() , pop()。
               pop()操作仅仅返回队首元素, 因此时间复杂度O(1)。
               push_back()操作,均摊下来每次操作的时间复杂度O(1):1.消除所有不可能的解     2.更新队首指针使其指向最优解

http://poj.org/problem?id=2823

题意 : 有一个窗口,让其从数组的最左端移动到最右端,求每次移动后窗口中的最大值与最小值。

 

// 2823 Moving Window.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
bool comp_for_max( const int newAppear, const int rear )
{
// Max MonQueue
return newAppear >= rear;
}
bool comp_for_min( const int newAppear, const int rear )
{
// Min MonQueue
return !(newAppear >= rear);
}
/*
*  单调队列模板
*  建议单调队列大小与数组相同
*/
struct MonQueue {
// 数据
int* q;
int top, rear, winLen;
bool is_empty;
// 构造与析构
MonQueue( const int n, const int winLen ) {
q = new int
;
top = rear = 0;
this->winLen = winLen; // 窗体长度
is_empty = true; // 初始化为空
}
~MonQueue( void ) {
delete [] q;
}

// 操作
/*
*  功能 : 将a[index]添加进单调队列
*  参数 : a[] in, 被添加元素所在数组
*         index in, 被添加元素的下标
*         comp in, 函数指针,用于实现单调队列的单调性
*  返回 : 无
*/
void Push_Back( int a[], int index, bool (*comp)(const int,const int) ) {
// 添加
if( is_empty ) {
q[top] = index;
is_empty = false;
return;
}
while( top <= rear && comp(a[index],a[q[rear]]) )
-- rear;
q[ ++rear ] = index;
// 更改队首
while( index - q[top] >= winLen )
++ top;
}
/*
*  功能 : 获取队首元素下标
*/
int Pop( void ) {
return q[top];
}
};
// 对象
int a[1000000], len;
int winLen; // 窗体长度
MonQueue *qMax, *qMin; // 最大,最小单调队列
int res1[1000000], res2[1000000];
int main()
{
while( scanf( "%d%d", & len, & winLen ) != EOF )
{
for( int i = 0; i < len; ++ i )
scanf( "%d", & a[i] );
MonQueue* qMax = new MonQueue( len, winLen );
MonQueue* qMin = new MonQueue( len, winLen );
// 初始化第一个窗口
for( int i = 0; i < winLen; ++ i ) {
qMax->Push_Back( a, i, comp_for_max );
qMin->Push_Back( a, i, comp_for_min );
}
res1[0] = a[ qMax->Pop() ];
res2[0] = a[ qMin->Pop() ];

// 移动窗口
for( int i = winLen; i < len; ++ i ) {
qMax->Push_Back( a, i, comp_for_max );
qMin->Push_Back( a, i, comp_for_min );
res1[ i-winLen+1 ] = a[ qMax->Pop() ];
res2[ i-winLen+1 ] = a[ qMin->Pop() ];
}
// 打印
for( int i = 0; i < len - winLen + 1; ++ i ) printf( "%d ", res2[i] ); // 先打印窗口中的最小值
cout << "/n";
for( int i = 0; i < len - winLen + 1; ++ i ) printf( "%d ", res1[i] ); // 打印窗口中的最大值
cout << "/n";
delete qMax;
delete qMin;
}
system( "pause" );
return 0;
}
 

 

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  delete system