zoukankan      html  css  js  c++  java
  • 单调栈(G

    题目链接:https://cn.vjudge.net/contest/276251#problem/G

    题目大意:给你n和m,然后问你对于(m,n)这中间的每一个数,(i-m+1,i)这个区间的最小值和最大值。

    具体思路:单调队列,对于个数的控制,我们通过队列来实现一个模拟的滑动窗口。然后最值的寻找,我们可以通过控制队列保持单调递增或者单调递减来实现。

    STL AC代码(耗时:10985s):

     1 #include<iostream>
     2 #include<stack>
     3 #include<cmath>
     4 #include<string>
     5 #include<stdio.h>
     6 #include<algorithm>
     7 #include<cstring>
     8 #include<queue>
     9 using namespace std;
    10 # define inf 0x3f3f3f3f
    11 # define ll long long
    12 const int maxn = 1e6+100;
    13 int minn[maxn],maxx[maxn],sto[maxn];
    14 inline int read1()
    15 {
    16     int f=1,x=0;
    17     char s=getchar();
    18     while(s<'0' || s>'9')
    19     {
    20         if(s=='-')
    21             f=-1;
    22         s=getchar();
    23     }
    24     while(s>='0' && s<='9')
    25     {
    26         x=x*10+s-'0';
    27         s=getchar();
    28     }
    29     return x*f;
    30 }
    31 int main()
    32 {
    33     int n,m;
    34     n=read1();
    35     m=read1();
    36     // scanf("%d %d",&n,&m);
    37     deque<int>q1;
    38     deque<int >q2;
    39     int tot=0,tmp;
    40     for(int i=1;i<=n;i++){
    41     sto[i]=read1();
    42     }
    43     for(int i=1; i<=n; i++)
    44     {
    45         while(!q1.empty()&&q1.front()<i-m+1)//先判断左边界有没有超出范围
    46             q1.pop_front();
    47         while(!q1.empty()&&sto[i]<sto[q1.back()])//保持队列单调递增
    48         {
    49             q1.pop_back();
    50         }
    51         q1.push_back(i);
    52         if(i>=m)
    53             minn[++tot]=q1.front();
    54         while(!q2.empty()&&q2.front()<i-m+1)
    55             q2.pop_front();
    56         while(!q2.empty()&&sto[i]>sto[q2.back()])
    57         {
    58             q2.pop_back();
    59         }
    60         q2.push_back(i);
    61         if(i>=m)
    62             maxx[tot]=q2.front();
    63     }
    64     for(int i=1; i<=tot; i++)
    65     {
    66         if(i==1)
    67             printf("%d",sto[minn[i]]);
    68         else
    69             printf(" %d",sto[minn[i]]);
    70     }
    71     printf("
    ");
    72     for(int i=1; i<=tot; i++)
    73     {
    74         if(i==1)
    75             printf("%d",sto[maxx[i]]);
    76         else
    77             printf(" %d",sto[maxx[i]]);
    78     }
    79     printf("
    ");
    80     return 0;
    81 }

    数组模拟(耗时:7152ms)AC代码:

     1 #include<iostream>
     2 #include<stack>
     3 #include<cmath>
     4 #include<string>
     5 #include<stdio.h>
     6 #include<algorithm>
     7 #include<cstring>
     8 #include<queue>
     9 using namespace std;
    10 # define inf 0x3f3f3f3f
    11 # define ll long long
    12 const int maxn = 1e6+100;
    13 int minn[maxn],maxx[maxn],sto[maxn];
    14 int moni[maxn];
    15 inline int read1()
    16 {
    17     int f=1,x=0;
    18     char s=getchar();
    19     while(s<'0' || s>'9')
    20     {
    21         if(s=='-')
    22             f=-1;
    23         s=getchar();
    24     }
    25     while(s>='0' && s<='9')
    26     {
    27         x=x*10+s-'0';
    28         s=getchar();
    29     }
    30     return x*f;
    31 }
    32 int main()
    33 {
    34     int n,m;
    35     n=read1();
    36     m=read1();
    37     int l=1,r=0;
    38     int tot=0;
    39     for(int i=1; i<=n; i++)
    40     {
    41         sto[i]=read1();
    42     }
    43     for(int i=1; i<=n; i++)
    44     {
    45         while(l<=r&&moni[l]<i-m+1)
    46             l++;
    47         while(l<=r&&sto[i]<sto[moni[r]]){
    48             r--;
    49         }
    50              moni[++r]=i;
    51         if(i>=m)
    52             minn[++tot]=moni[l];
    53     }
    54     l=1,r=0,tot=0;
    55     for(int i=1; i<=n; i++)
    56     {
    57         while(l<=r&&moni[l]<i-m+1)
    58             l++;
    59         while(l<=r&&sto[i]>sto[moni[r]]){
    60             r--;
    61         }
    62              moni[++r]=i;
    63         if(i>=m)
    64             maxx[++tot]=moni[l];
    65     }
    66     for(int i=1; i<=tot; i++)
    67     {
    68         if(i==1)
    69             printf("%d",sto[minn[i]]);
    70         else
    71             printf(" %d",sto[minn[i]]);
    72     }
    73     printf("
    ");
    74     for(int i=1; i<=tot; i++)
    75     {
    76         if(i==1)
    77             printf("%d",sto[maxx[i]]);
    78         else
    79             printf(" %d",sto[maxx[i]]);
    80     }
    81     printf("
    ");
    82     return 0;
    83 }

    (我太菜了,,,数组模拟调了半个小时。。)

  • 相关阅读:
    高中时的口头禅
    我想跟你说
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10262750.html
Copyright © 2011-2022 走看看