题目原网址: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 }