题目链接:点击打开链接
思路:单调队列入门题目
代码一:
// POJ 2823 Sliding Window 运行/限制:5532ms/12000ms 用C++交的,G++超时了
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int n, k;
int a[1000005],queue[1000005];
void minQueue() {
int head = 1, tail = 0;
queue[head] = 1;
for (int i = 0; i < n; i++) {
//删除队首元素
if (i - queue[head] == k) head++;
//直接放在队尾
if (head - tail == 1 || a[i] > a[queue[tail]]) {//第一个条件指的是队列为空
queue[++tail] = i;
}
else {//不断删除队尾元素找到合适位置
while (tail >= head && a[i] <= a[queue[tail]]) {
tail--;
}
queue[++tail] = i;
}
if (i >= k - 1) {
printf("%d%c", a[queue[head]], i == n - 1 ? '\n' : ' ');
}
}
}
void maxQueue() {
int head = 1, tail = 0;
queue[head] = 1;
for (int i = 0; i < n; i++) {
//删除队首元素
if (i - queue[head] == k) head++;
//直接放在队尾
if (head - tail == 1 || a[i] < a[queue[tail]]) {//第一个条件指的是队列为空
queue[++tail] = i;
}
else {//不断删除队尾元素找到合适位置
while (tail >= head && a[i] >= a[queue[tail]]) {
tail--;
}
queue[++tail] = i;
}
if (i >= k - 1) {
printf("%d%c", a[queue[head]], i == n - 1 ? '\n' : ' ');
}
}
}
int main(){
scanf("%d%d", &n, &k);
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
minQueue();
maxQueue();
return 0;
}
代码二:
// POJ 2823 Sliding Window 运行/限制:5516ms/12000ms 用C++交的,G++超时了
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int n, k;
int a[1000005];//原序列
int minQueue[1000005],maxQueue[1000005];//单调递减队列 单调递增队列
int minRe[1000005],maxRe[1000005];//结果
void solve() {
int minHead = 1, minTail = 0;//单调递减序列头、尾
int maxHead = 1, maxTail = 0;//单调递增序列头、尾
for (int i = 0; i < n; i++) {
//处理单调递减序列
while (minTail >= minHead && a[i] <= a[minQueue[minTail]]) {
minTail--;
}
minQueue[++minTail] = i;
if(i - minQueue[minHead] == k) minHead++;
//处理单调递增序列
while (maxTail >= maxHead && a[i] >= a[maxQueue[maxTail]]) {
maxTail--;
}
maxQueue[++maxTail] = i;
if(i - maxQueue[maxHead] == k) maxHead++;
//存储结果
if(i >= k - 1){
minRe[i] = a[minQueue[minHead]];
maxRe[i] = a[maxQueue[maxHead]];
}
}
//打印结果
for(int i = k - 1;i < n;i++){
printf("%d%c",minRe[i],i == n - 1?'\n':' ');
}
for(int i = k - 1;i < n;i++){
printf("%d%c",maxRe[i],i == n - 1?'\n':' ');
}
}
int main(){
scanf("%d%d", &n, &k);
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
solve();
return 0;
}