1. 程式人生 > >[poj2823]sliding windows(單調佇列模板題)

[poj2823]sliding windows(單調佇列模板題)

Description

An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves rightwards by one position. Following is an example: 
The array is [1 3 -1 -3 5 3 6 7]
, and k is 3.
Window positionMinimum valueMaximum value
[1  3  -1] -3  5  3  6  7 -13
 1 [3  -1  -3] 5  3  6  7 -33
 1  3 [-1  -3  5] 3  6  7 -35
 1  3  -1 [-3  5  3] 6  7 -35
 1  3  -1  -3 [5  3  6] 7 36
 1  3  -1  -3  5 [3  6  7]37

Your task is to determine the maximum and minimum values in the sliding window at each position. 

Input

The input consists of two lines. The first line contains two integers n and k which are the lengths of the array and the sliding window. There are n integers in the second line. 

Output

There are two lines in the output. The first line gives the minimum values in the window at each position, from left to right, respectively. The second line gives the maximum values. 

Sample Input

8 3
1 3 -1 -3 5 3 6 7

Sample Output

-1 -3 -3 -3 3 3
3 3 5 5 6 7

這道題很明顯用單調佇列。每到一個新的區間,都判斷當前佇列的首位是否已不在這個區間,如果不在,就把隊首出隊。加入新元素。每加入一個元素,都從佇列尾往前遍歷,如果當前結單大於或小於(要寫兩個佇列)要放進的結點,就從後面把這個元素出隊。這個操作比較騷,所以我們寫出來的東西不是嚴謹的佇列,而是一個有棧性質的佇列。這就有點騷了,所以我們必須手寫一個這樣的奇怪的玩意。

第一次的提交的時候tle了,看來poj對我的惡意不小啊。然後抱著僥倖心理加了一個讀優,然後就AC了,23333。

不多bb我放程式碼了,arr存陣列,有兩個佇列max_queue和min queue對應max tail等。

#include<iostream>
#include<cctype>
#include<cstdio>
using namespace std;
int arr[1000000];
int max_queue[1000000], min_queue[1000000], max_tail, min_tail, max_head = 1, min_head = 1;
int N, K;
inline int  read()
{
	int X = 0, w = 0; char ch = 0;
	while (!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
	while (isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
	return w ? -X : X;
}
bool max_empty()
{
	if (max_tail == max_head - 1)
		return true;
	else
		return false;
}
bool min_empty()
{
	if (min_tail == min_head - 1)
		return true;
	else
		return false;
}
void min_push(int a)
{
	//if(!min_empty()) 
	while (arr[a] <= arr[min_queue[min_tail]] && !min_empty())
		min_tail--;
	min_tail++;
	min_queue[min_tail] = a;
}
void max_push(int a)
{
	while (arr[a] > arr[max_queue[max_tail]] && !max_empty())
		max_tail--;
	max_tail++;
	max_queue[max_tail] = a;
}
int min_top()
{
	return min_queue[min_head];
}
int max_top()
{
	return max_queue[max_head];
}
void min_pop()
{
	min_head++;
}
void max_pop()
{
	max_head++;

}
int main()
{
	cin >> N >> K;
	for (int i = 1; i <= N; i++)
	{
		arr[i]=read();
	}
	for (int i = 1; i <= K; i++)
	{
		min_push(i);
	}
	cout << arr[min_top()] << " ";
	for (int i = 1; i <= N - K; i++)
	{
		if (min_top() == i)
			min_pop();
		min_push(i + K);
		cout << arr[min_top()] << " ";
	}
	cout << endl;
	for (int i = 1; i <= K; i++)
	{
		max_push(i);
	}
	cout << arr[max_top()] << " ";
	for (int i = 1; i <= N - K; i++)
	{
		//cout<<"max "<<max_top()<<" ";
		if (max_top() == i)
			max_pop();
		max_push(i + K);
		cout << arr[max_top()] << " ";
	}
	//system("pause");
}