cstdios @ 2019-10-04 19:13:51
AC了一个点,请大佬们指点我一下:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>//头文件
#define maxn 2000100
using namespace std;
int q[maxn], a[maxn];//q为记录a数组的下标,a为读入的元素
int n, k;//看题目
void getmin() {//维护最小值
int head = 0, tail = 0;//头尾指针
for (int i = 1; i < k; i++) {
while (head <= tail && a[q[tail]] >= a[i]) tail--;
q[tail++] = i;
}
//假设数据是 1 2 3 4 5 head=0 tail=0 a:1 2 3 4 5 q:0
//i=1 head=0 tail=1 a:1 2 3 4 5 q:0 1
for (int i = k; i <= n; i++) {
while (head <= tail && a[q[tail]] >= a[i]) tail--;
q[++tail] = i;
while (q[head] <= i - k) head++;
printf("%d ", a[q[head]]);
}
// 然后开始 i=2 head =1 tail=1 a[1]>=a[2]条件不成立跳出,q[head=1]<=(i-k=0) q:0 1 2 输出 1
//i=3 ....
}
void getmax() {
int head = 0, tail = 0;
for (int i = 1; i < k; i++) {
while (head <= tail && a[q[tail]] <= a[i]) tail--;
q[++tail] = i;
}
for (int i = k; i <= n; i++) {
while (head <= tail && a[q[tail]] <= a[i]) tail--;
q[++tail] = i;
while (q[head] <= i - k) head++;
printf("%d ", a[q[head]]);
}
}
int main() {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
getmin();
printf("\n");
getmax();
printf("\n");
return 0;
}
by Cwling @ 2019-10-04 19:22:42
推荐STL。STL大法好!
by Cwling @ 2019-10-04 19:27:36
你这个问题很明显
while (head <= tail && a[q[tail]] >= a[i]) tail--;
q[tail++] = i;
}
//假设数据是 1 2 3 4 5 head=0 tail=0 a:1 2 3 4 5 q:0
//i=1 head=0 tail=1 a:1 2 3 4 5 q:0 1
for (int i = k; i <= n; i++) {
while (head <= tail && a[q[tail]] >= a[i]) tail--;
q[++tail] = i;
while (q[head] <= i - k) head++;
printf("%d ", a[q[head]]);
}
这一段问题就很大。 第一,我觉得应该只要一个for(1-n)就好了。 第二,你这个单调队列维护有很大问题,建议去看看别人的单调队列模板。对于单调队列我更推荐你去学一下STL双端队列的单调队列,挺好用的。如果你要的话我可以帮你写一下。
by cstdios @ 2019-10-04 19:34:38
@蔓翎 谢谢