• POJ 2823 Sliding Window(单调队列)


    题目链接:Sliding Window

    题意:给定n长度的数字序列,求从前往后每k个数字中的最大值和最小值分别为多少。

    题解:单调队列。(除去冗余状态)整个思路就是尽量删掉没用的数字,从队列尾部删掉价值不如当前的,从队列头部删掉序号不在该区间内的。

    数组版:

     1 #include <cstdio>
     2 using namespace std;
     3 
     4 const int N=1e6+10;
     5 typedef long long ll;
     6 int n,k;
     7 ll a[N];
     8 
     9 struct node{
    10     int id;
    11     ll val;
    12 }q[N];
    13 
    14 void getmin(){
    15     int head=1,tail=0;
    16     for(int i=1;i<=n;i++){
    17         while(head<=tail&&q[tail].val>=a[i]) tail--;
    18         q[++tail].val=a[i];q[tail].id=i;
    19         if(i>=k){
    20             while(head<=tail&&q[head].id<=i-k) head++;
    21             printf("%lld ",q[head].val);
    22         }
    23     }
    24     printf("
    ");
    25 }
    26 
    27 void getmax(){
    28     int head=1,tail=0;
    29     for(int i=1;i<=n;i++){
    30         while(head<=tail&&q[tail].val<=a[i]) tail--;
    31         q[++tail].val=a[i];q[tail].id=i;
    32         if(i>=k){
    33             while(head<=tail&&q[head].id<=i-k) head++;
    34             printf("%lld ",q[head].val);
    35         }
    36     }
    37     printf("
    ");
    38 }
    39 
    40 int main(){
    41     scanf("%d%d",&n,&k);
    42     for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    43     getmin();
    44     getmax();
    45     return 0;
    46 }
    View Code

     deque版:

     1 #include <queue>
     2 #include <cstdio>
     3 using namespace std;
     4 
     5 const int N=1e6+10;
     6 int n,k;
     7 int a[N];
     8 deque <int> q1,q2;
     9 
    10 void getmin(){
    11     for(int i=1;i<=n;i++){
    12         while(!q1.empty()&&a[i]<=a[q1.back()]) q1.pop_back();
    13         q1.push_back(i);
    14         if(i>=k){
    15             while(!q1.empty()&&q1.front()<=i-k) q1.pop_front();
    16             printf("%d ",a[q1.front()]);
    17         }
    18     }
    19     printf("
    ");
    20 }
    21 
    22 void getmax(){
    23     for(int i=1;i<=n;i++){
    24         while(!q2.empty()&&a[i]>=a[q2.back()]) q2.pop_back();
    25         q2.push_back(i);
    26         if(i>=k){
    27             while(!q2.empty()&&q2.front()<=i-k) q2.pop_front();
    28             printf("%d ",a[q2.front()]);
    29         }
    30     }
    31     printf("
    ");
    32 }
    33 
    34 int main(){
    35     scanf("%d%d",&n,&k);
    36     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    37     getmin();
    38     getmax();
    39     return 0;
    40 }
    View Code
  • 相关阅读:
    项目人力资源管理
    以太网交换机
    邮件协议简单学习
    信息系统开发方法
    项目成本管理
    oracle学习笔记002---oracle的体系结构
    007 项目进度管理
    乘法逆元
    RMQ __ST
    中国剩余定理(CRT)
  • 原文地址:https://www.cnblogs.com/pavtlly/p/9996122.html
Copyright © 2020-2023  润新知