【COGS495】窗口

【问题描述】

给你一个长度为N的数组,一个长为K的滑动的窗体从最左移至最右端,你只能见到窗口的K个数,每次窗体向右移动一位,如下表:

Window position Min value Max value
[1 3 -1] -3 5 3 6 7 -1 3
1 [3 -1 -3] 5 3 6 7 -3 3
1 3 [-1 -3 5]3 6 7 -3 5
1 3 -1 [-3 5 3] 6 7 -3 5
1 3 -1 -3 [5 3 6] 7 3 6
1 3 -1 -3 5 [3 6 7 ] 3 7


你的任务是找出窗口在各位置时的max value,min value.

 

【输入格式】

第一行n,k,第二行为长度为n的数组

 

【输出格式】

第一行每个位置的min value,第二行每个位置的max value

 

【分析】

好吧,其实我不想发上来的,纯粹凑数。

裸的单调队列。

 

 1 #include <cstdlib>

 2 #include <iostream>

 3 #include <cstdio>

 4 #include <cmath>

 5 #include <algorithm>

 6 #include <cstring>

 7 const int maxn=1000010;

 8 const int INF=0x7fffffff;

 9 using namespace std;

10 struct que{int shu[maxn],l,r;}Q_max,Q_min; 

11 void solve();

12 void print(); 

13 int data[maxn],n,k;

14 int ans[2][maxn];

15 

16 int main()

17 {

18     //文件操作

19     freopen("window.in","r",stdin);

20     freopen("window.out","w",stdout); 

21     scanf("%d%d",&n,&k);

22     for (int i=1;i<=n;i++) scanf("%d",&data[i]);

23     solve();//滑动窗口

24     print();//打印 

25     return 0;

26 }

27 void solve()

28 {

29      //拉上窗口

30      int i;

31      Q_max.l=Q_min.l=Q_max.r=Q_min.r=1;//初始化指针 

32      for (i=1;i<=k;i++) 

33      {

34          while (Q_max.l<Q_max.r && Q_max.shu[Q_max.l]<i-k+1) Q_max.l++;

35          while (Q_min.l<Q_min.r && Q_min.shu[Q_min.l]<i-k+1) Q_min.l++;

36          while (Q_max.l<Q_max.r && data[Q_max.shu[Q_max.r-1]]<data[i]) Q_max.r--;

37          while (Q_min.l<Q_min.r && data[Q_min.shu[Q_min.r-1]]>data[i]) Q_min.r--;

38          Q_max.shu[Q_max.r++]=i;Q_min.shu[Q_min.r++]=i;

39      }

40      //注意窗口永远指向窗口最右端 

41      for (i=k;i<=n;i++) 

42      {

43          while (Q_max.l<Q_max.r && Q_max.shu[Q_max.l]<i-k+1) Q_max.l++;

44          while (Q_min.l<Q_min.r && Q_min.shu[Q_min.l]<i-k+1) Q_min.l++;

45          ans[0][i]=Q_max.shu[Q_max.l];ans[1][i]=Q_min.shu[Q_min.l];//标记打印 

46          while (Q_max.l<Q_max.r && data[Q_max.shu[Q_max.r-1]]<data[i+1]) Q_max.r--;

47          while (Q_min.l<Q_min.r && data[Q_min.shu[Q_min.r-1]]>data[i+1]) Q_min.r--;

48          Q_max.shu[Q_max.r++]=i+1;Q_min.shu[Q_min.r++]=i+1;

49      }

50 }

51 void print()

52 {

53      for (int i=k;i<=n;i++) printf("%d ",data[ans[1][i]]);

54      printf("\n");

55      for (int i=k;i<=n;i++) printf("%d ",data[ans[0][i]]);

56 }

 

你可能感兴趣的:(窗口)