タイトルコンテンツは
、それぞれ、最大値と最小値の数毎に長さを有し、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] << ' ';
}
}