Week5:スライディングウィンドウ - モノトーンキュー

タイトルコンテンツは
、それぞれ、最大値と最小値の数毎に長さを有し、n列の数とサイズkのウィンドウ、ウィンドウはバックを移動し、前後の列にすることができる。スライディングウィンドウの左から右に、知りたい、窓何例:
列の数は、kが3に等しい[13-1-35367]、ある
ここに画像を挿入説明
入力フォーマットが
入力された2行です。二つの整数nとkの最初の行はサイズおよびスライディングウィンドウシリーズ、1 <= K <= Nの長さ <= 1000000。n列の整数を表し有する第2の行が分析されます。

出力フォーマット
出力2つの系統。左から右へ、各スライディングウィンドウ位置の第1の出力ライン、スライディングウィンドウ内の最小値。2行目は最大です。

サンプル入力

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

サンプル出力

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

トピック分析
明らかには、解決した場合、各セグメントの暴力のために、一度大きなアップ、直接、すべての神のその時の複雑さをk個。
この質問のために、我々は、我々は唯一の範囲内のすべての単調一度維持することができ、このように単調なキューを維持することができ、かつ両端キュー両端キューを使用しています。
この両端キューを維持し、左端点の位置は、このキューの開始点とみなし、各時間のキュー(すなわち、窓)が移動すると、単調性右、投げ出さより左境界点を維持し、それだけで可能です各区間における最小値を得るために、もう一度スキャン。

共感の最大値。

#include <iostream>
#include <vector>
#include <string>
#include <deque>
using namespace std;

int n, k;

struct Point
{
	int num;
	int index;
	Point(int n,int i):num(n),index(i){}
};

deque<Point>minwindow;
deque<Point>maxwindow;
vector<int>minans;
vector<int>maxans;

void insert(Point p)
{
	while (!minwindow.empty() && minwindow.back().num > p.num)  minwindow.pop_back();
	minwindow.push_back(p);

	while (!maxwindow.empty() && maxwindow.back().num < p.num)  maxwindow.pop_back();
	maxwindow.push_back(p);
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin >> n >> k;

	int temp;
	//初始化
	for (int i = 0; i < k - 1; i++)
	{
		cin >> temp;
		Point t(temp, i);

		insert(t);
	}

	for (int i = k - 1; i < n; i++)
	{
		int index = i - k + 1;//窗口最左边的位置
		cin >> temp;
		Point t(temp, i);

		insert(t);
		//弹出窗口最左边之前的数
		while (minwindow.front().index < index) minwindow.pop_front();
		while (maxwindow.front().index < index) maxwindow.pop_front();

		minans.push_back(minwindow.front().num);
		maxans.push_back(maxwindow.front().num);
	}

	for (int i = 0; i < minans.size(); i++)
	{
		cout << minans[i] << ' ';
	}

	cout << endl;

	for (int i = 0; i < maxans.size(); i++)
	{
		cout << maxans[i] << ' ';
	}
}
公開された21元の記事 ウォンの賞賛3 ビュー406

おすすめ

転載: blog.csdn.net/qq_44506233/article/details/105105845