• 洛谷 P1886 滑动窗口(单调队列)


    题目原网址:https://www.luogu.org/problemnew/show/P1886

    解题思路:

    维护一个单调队列,

    假如我们先求最小值,保证队首就是最小值,满足滑动窗口长度时输出队首;

    例如样例 1 3 -1 -3 5 3 6 7

    第一步 1 先入队了

    第二步  1 小于3 没问题 所以3接着入队了

    第三步   1和3 都大于-1 所以1和3都弹出  -1入队  此时刚好满足长度为k(k=3)的滑动窗口,输出队首 -1

    第四步  -1 大于 -3 所以-1弹出 -3 入队  输出队首-3

    第五步 -3 小于5 没问题  5入队 输出队首-3

    第六步  5大于3  那5不论怎么样都不可能是最小值了,所以弹出5  ,3入队,输出队首-3

    第六步  3小于6没问题  6入队,此时滑动窗口覆盖范围已经走到了(5,3,6) 所以要将-3 出队,输出队首3

    第七步 6小于7没问题   ,7入队,输出队首3

     求最大值的话同理

    //以上转载自:https://www.cnblogs.com/llke/p/10780121.html

    AC代码:

      1 #include<cstdio>
      2 #include<queue>
      3 #include<iostream>
      4 
      5 using namespace std;
      6 
      7 deque<int> l;
      8 queue<int> _min,_max;
      9 int n,k,num[1000001];
     10 
     11 void findmin() {
     12     int minid = 1,o,minn = 0x7f7f7f,ts;
     13     for(int i = 1;i <= k; i++) {
     14         if(l.empty()) 
     15             l.push_back(i);
     16         o = num[i];
     17         if(o <= minn) {
     18             minn = o;
     19             minid = i;
     20             while(!l.empty()) {
     21                 o = l.front();
     22                 if(num[o] >= minn) 
     23                     l.pop_front();
     24                 else break;
     25             }
     26             l.push_front(minid);
     27         }
     28         else {
     29             while(!l.empty()) {
     30                 o = l.back();
     31                 if(num[o] >= num[i]) 
     32                     l.pop_back();
     33                 else break;
     34             }
     35             l.push_back(i);
     36         }
     37     }
     38     _min.push(minn);
     39     for(int i = k + 1;i <= n; i++) {
     40         if(minid <= i - k) {
     41             l.pop_front();
     42             minid = l.front();
     43             minn = num[minid];
     44         }
     45         if(l.empty()) l.push_back(i);
     46         o = num[i];
     47         if(o <= minn) {
     48             minn = o;
     49             minid = i;
     50             while(!l.empty()) {
     51                 o = l.front();
     52                 if(num[o] >= minn)
     53                     l.pop_front();
     54                 else break;
     55             }
     56             l.push_front(minid);
     57         }
     58         else {
     59             while(!l.empty()) {
     60                 o = l.back();
     61                 if(num[o] >= num[i]) 
     62                     l.pop_back();
     63                 else break;
     64             }
     65             l.push_back(i);
     66         }
     67         _min.push(minn);
     68     }
     69     while(!_min.empty()) {
     70         cout << _min.front() << " " ;
     71         _min.pop();
     72     }
     73     cout << endl;
     74 }
     75 
     76 void findmax() {
     77     int maxid = 1,o,maxx = -0x7f7f7f;
     78     for(int i = 1;i <= k; i++) {
     79         if(l.empty()) 
     80             l.push_back(i);
     81         o = num[i];
     82         if(o >= maxx) {
     83             maxx = o;
     84             maxid = i;
     85             while(!l.empty()) {
     86                 o = l.front();
     87                 if(num[o] <= maxx) 
     88                     l.pop_front();
     89                 else break;
     90             }
     91             l.push_front(maxid);
     92         }
     93         else {
     94             while(!l.empty()) {
     95                 o = l.back();
     96                 if(num[o] <= num[i]) 
     97                     l.pop_back();
     98                 else break;
     99             }
    100             l.push_back(i);
    101         }
    102     }
    103     _max.push(maxx);
    104     for(int i = k + 1;i <= n; i++) {
    105         if(maxid <= i - k) {
    106             l.pop_front();
    107             maxid = l.front();
    108             maxx = num[maxid];
    109         }
    110         if(l.empty()) l.push_back(i);
    111         o = num[i];
    112         if(o >= maxx) {
    113             maxx = o;
    114             maxid = i;
    115             while(!l.empty()) {
    116                 o = l.front();
    117                 if(num[o] <= maxx)
    118                     l.pop_front();
    119                 else break;
    120             }
    121             l.push_front(maxid);
    122         }
    123         else {
    124             while(!l.empty()) {
    125                 o = l.back();
    126                 if(num[o] <= num[i]) 
    127                     l.pop_back();
    128                 else break;
    129             }
    130             l.push_back(i);
    131         }
    132         _max.push(maxx);
    133     }
    134     while(!_max.empty()) {
    135         cout << _max.front() << " ";
    136         _max.pop();
    137     }
    138 }
    139 
    140 bool tepan() {
    141     if(k == 1) {
    142         for(int i = 1;i <= n; i++)
    143             cout << num[i] << " ";
    144         cout << endl;
    145         for(int i = 1;i <= n; i++)
    146             cout << num[i] << " ";
    147         return true;
    148     }
    149     else return false;
    150 }
    151 
    152 int main() {
    153     scanf("%d%d",&n,&k);
    154     for(int i = 1;i <= n; i++) 
    155         scanf("%d",&num[i]);
    156     if(tepan()) return 0;
    157     findmin();
    158     while(!l.empty()) l.pop_back();
    159     findmax();
    160     return 0;
    161 }
  • 相关阅读:
    python 学习
    快速排序
    U3D AStar 案例
    U3D AStar 算法原理
    .net core 实时通讯
    .net 算法复杂度
    U3D MVC 背包案例
    U3D 对象池
    Unity网络基础(NetWork)
    U3D Socket实现简易通讯
  • 原文地址:https://www.cnblogs.com/lipeiyi520/p/11237335.html
Copyright © 2020-2023  润新知