麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

POJ 2823 Sliding Window (單調隊列的學習)

2019-11-14 12:17:56
字體:
來源:轉載
供稿:網友
An array of size n ≤ 10 6 is given to you. There is a sliding window of size kwhich 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. 

InputThe 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. OutputThere 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 31 3 -1 -3 5 3 6 7Sample Output
-1 -3 -3 -3 3 3

3 3 5 5 6 7

題目大意:給你一個數組,然后讓從左到右,找到每連續k個數的最大值和最小值并且輸出

題目分析:單調隊列解決,然后用C++卡時間AC,用G++會超時

這個問題相當于一個數據流(數列a)在不斷地到來,而數據是不斷過期的,相當于我們只能保存有限的數據(sliding window中的數據,此題中就是窗口的寬度w),對于到來的查詢(此題中查詢是每時刻都有的),我們要返回當前滑動窗口中的最大值/最小值。注意,元素是不斷過期的。

解決這個問題可以使用一種叫做單調隊列的數據結構,它維護這樣一種隊列:

a)從隊頭到隊尾,元素在我們所關注的指標下是遞減的(嚴格遞減,而不是非遞增),比如查詢如果每次問的是窗口內的最小值,那么隊列中元素從左至右就應該遞增,如果每次問的是窗口內的最大值,則應該遞減,依此類推。這是為了保證每次查詢只需要取隊頭元素。

b)從隊頭到隊尾,元素對應的時刻(此題中是該元素在數列a中的下標)是遞增的,但不要求連續,這是為了保證最左面的元素總是最先過期,且每當有新元素來臨的時候一定是插入隊尾。

滿足以上兩點的隊列就是單調隊列,首先,只有第一個元素的序列一定是單調隊列。

那么怎么維護這個單調隊列呢?無非是處理插入和查詢兩個操作。

對于插入,由于性質b,因此來的新元素插入到隊列的最后就能維持b)繼續成立。但是為了維護a)的成立,即元素在我們關注的指標下遞減,從隊尾插入新元素的時候可能要刪除隊尾的一些元素,具體說來就是,找到第一個大于(在所關注指標下)新元素的元素,刪除其后所有元素,并將新元素插于其后。因為所有被刪除的元素都比新元素要小,而且比新元素要舊,因此在以后的任何查詢中都不可能成為答案,所以可以放心刪除。

對于查詢,由于性質b,因此所有該時刻過期的元素一定都集中在隊頭,因此利用查詢的時機刪除隊頭所有過期的元素,在不含過期元素后,隊頭得元素就是查詢的答案(性質a),將其返回即可。

由于每個元素都進隊出隊一次,因此攤銷復雜度為O(n)。

程序實現過程中先將前k個元素入隊,此后每次在隊尾加入a[k+1...n],在插入元素中同時進行以下操作:

1、將隊尾所有大于a[i]的值彈出隊列

2、插入a[i]到隊尾

3、判斷隊首元素位置是否超出i-k

注意:

1、在更新隊列元素時要同時記錄該元素在原數據的位置

2、在進行操作1時要用二分優化(可以用C++編譯器卡時間AC,但換成G++和GCC就會TLE)

#include <iostream>#include <fstream>#define maxn 1000010using namespace std;int a[maxn],q[maxn],p[maxn],Min[maxn],Max[maxn],n,k;// a是數據,q是隊列,p是存放下標void gmin(){	int tail=0,head=1,i;	for(i=0;i<k-1;i++){		while(head<=tail && q[tail]>=a[i])//若添加的元素小于隊尾元素,符合條件,刪除隊尾元素,直到隊尾元素小于此元素為止 		  --tail;		q[++tail]=a[i];//存放滿足條件的數據 		p[tail]=i;//記錄存儲的數據下標,保證每個窗口所讀入的數據都在k的范圍內 	}	for(;i<n;i++){		while(head<=tail && q[tail]>=a[i])		 --tail;		q[++tail]=a[i];		p[tail]=i;		while(p[head]<i-k+1)//利用查看數據是否過時,即是否在窗口內 		  ++head;	   Min[i-k+1]=q[head];//存放數據答案 	}} void gmax(){	int tail=0,head=1,i;	for(i=0;i<k-1;i++){		while(head<=tail && q[tail]<=a[i])		  --tail;		q[++tail]=a[i];		p[tail]=i;	}	for(;i<n;i++){		while(head<=tail && q[tail]<=a[i])		  --tail;		q[++tail]=a[i];		p[tail]=i;		while(p[head]<i-k+1)		   head++;		Max[i-k+1]=q[head];	}}	void output(){	for(int i=0;i<n-k;i++)	   PRintf("%d ",Min[i]);	   printf("%d/n",Min[n-k]);	for(int i=0;i<n-k;i++)	   printf("%d ",Max[i]);	   printf("%d/n",Max[n-k]);}int main(){	scanf("%d%d",&n,&k);	for(int i=0;i<n;i++)	  scanf("%d",&a[i]);	gmin();	gmax();	output();	return 0;}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 毛片在线免费观看完整版 | 亚洲一区在线视频观看 | 成人在线免费观看视频 | 久久一级| 日本综合久久 | chinese18 xxxx videos | 亚洲网站在线观看视频 | 日本高清在线免费 | 国产精品啪一品二区三区粉嫩 | 亚洲午夜国产 | 国产91精品久久久久久 | 欧美亚洲国产一区二区三区 | 91看片淫黄大片欧美看国产片 | 国产精品一区自拍 | 久久无毛 | 日韩欧美精品中文字幕 | 久久亚洲国产精品 | 特级西西444www大精品视频免费看 | 毛片观看网址 | 免费国产视频在线观看 | 久久久久久久一区 | 一级大黄毛片 | 欧美熟videos肥婆 | 99最新网址| 久久久久久久久成人 | 亚洲一二区精品 | hd欧美free性xxxx护土 | 一区二区三区欧美精品 | 欧美精品成人一区二区在线观看 | 成人区一区二区三区 | 国产精品美女久久久久久不卡 | 国产成人午夜精品 | 免费看黄色一级片 | 媚药按摩痉挛w中文字幕 | 久久国产精品久久精品国产演员表 | 偿还的影视高清在线观看 | 精品久久久久久久久久 | 沉沦的校花奴性郑依婷c到失禁 | 国产一区二区免费看 | 高潮激情aaaaa免费看 | 国产男女 爽爽爽爽视频 |