POJ-2823 單調隊列

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main_POJ2823 {
	static int[] a,q,id;
	static int n,k;
	static PrintWriter out = new PrintWriter(System.out);
	public static void main(String[] args) throws IOException {
		StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		sc.nextToken();
		n = (int)sc.nval;
		sc.nextToken();
		k = (int)sc.nval;
		q = new int[n+1];
		id = new int[n+1];
		a = new int[n+1];
		for(int i=1;i<=n;i++) {
			sc.nextToken();
			a[i] = (int)sc.nval;	
		}
		getmin();
		getmax();
	}
	public static void getmin() {  //維持單調遞增的序列
		int l = 1,r = 0;
		int i;
		for(i=1;i<k;i++) {   //先將前k-1個數入隊   
			while(l<=r&&q[r]>a[i]) r--;   //l<=r判斷是否爲空隊列  隊列中的所有元素都與新入隊的元素比較q[r]>a[i]是維持遞增   這樣隊頭就是最小元素
			q[++r] = a[i]; 
			id[r] = i;   
		}
		while(i<=n){
			while(l<=r&&q[r]>a[i]) r--;   //l<=r判斷是否爲空隊列  隊列中的所有元素都與新入隊的元素比較q[r]>a[i]是維持遞增   這樣隊頭就是最小元素
			q[++r] = a[i];     //大於a[i]的元素都將出隊    這裏是用指針模擬出隊
			id[r] = i;       
			while(id[l]<i-k+1) l++;   //判斷隊頭元素的下標是否屬於該滑動窗口  不屬於的話將其出隊 同樣是用指針模擬出隊
			out.print(q[l]+" ");
			i++;
		}
		out.println();
		out.flush();
	}
	public static void getmax() {  //同上  維持單調遞減的序列
		int l = 1,r = 0;
		int i;
		for(i=1;i<k;i++) {
			while(l<=r&&q[r]<a[i]) r--;
			q[++r] = a[i];
			id[r] = i;
		}
		while(i<=n){
			while(l<=r&&q[r]<a[i]) r--;
			q[++r] = a[i];
			id[r] = i;
			while(id[l]<i-k+1) l++;
			out.print(q[l]+" ");
			i++;
		}
		out.println();
		out.flush();
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章