POJ 2823 Sliding Window 双端队列入门题

今天比赛因为不会双端队列卡了几道题,今天好好学学。

 

双端队列一般保存2个值, 原数组的下标,数组中的值。

View Code
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxn 1000003
int a[maxn];
int n, m;

struct Queue
{
    int pos, val;
}que[maxn];
void getmin()
{
    int i;
    int head = 0, tail = -1;
    for(i = 0; i < m-1; i++)
    {
        while(head <= tail && que[tail].val > a[i])
            tail--;
        que[++tail].val = a[i];
        que[tail].pos = i;
    }
    for(i = m-1; i < n; i++)
    {
        while(head <= tail && i - que[head].pos >= m)
            head++;
        while(head <= tail && que[tail].val > a[i])
            tail--;
        que[++tail].val = a[i];
        que[tail].pos = i;
        if(i != n - 1)
            printf("%d ", que[head].val);
    }
    printf("%d\n", que[head].val);
}

void getmax()
{
    int i;
    int head = 0, tail = -1;
    for(i = 0; i < m-1; i++)
    {
        while(head <= tail && que[tail].val < a[i])
            tail--;
        que[++tail].val = a[i];
        que[tail].pos = i;
    }
    for(i = m-1; i < n; i++)
    {
        while(head <= tail && i - que[head].pos >= m)
            head++;
        while(head <= tail && que[tail].val < a[i])
            tail--;
        que[++tail].val = a[i];
        que[tail].pos = i; 
        if(i != n - 1)
            printf("%d ", que[head].val);
    }
    printf("%d\n", que[head].val);
}
int main()
{
    int i, j;
    while( ~scanf("%d%d", &n, &m))
    {
        for(i = 0; i < n; i++)
            scanf("%d", &a[i]);
        getmin();
        getmax();
    }
    return 0;
}

 

这里双端队列保存的值是原数组的下标,省去了一个变量

View Code
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxn 1000003
int a[maxn], que[maxn];
int n, m;

void getmin()
{
    int i;
    int head = 0, tail = -1;
    for(i = 0; i < m-1; i++)
    {
        while(head <= tail && a[que[tail]] > a[i])
            tail--;
        que[++tail] = i;
    }
    for(i = m-1; i < n; i++)
    {
        while(head <= tail && i - que[head] >= m)
            head++;
        while(head <= tail && a[que[tail]] > a[i])
            tail--;
        que[++tail] = i;
        if(i != n - 1)
            printf("%d ", a[que[head]]);
    }
    printf("%d\n", a[que[head]]);
}

void getmax()
{
    int i;
    int head = 0, tail = -1;
    for(i = 0; i < m-1; i++)
    {
        while(head <= tail && a[que[tail]] < a[i])
            tail--;
        que[++tail] = i;
    }
    for(i = m-1; i < n; i++)
    {
        while(head <= tail && i - que[head] >= m)
            head++;
        while(head <= tail && a[que[tail]] < a[i])
            tail--;
        que[++tail] = i;
        if(i != n - 1)
            printf("%d ", a[que[head]]);
    }
    printf("%d\n", a[que[head]]);
}
int main()
{
    int i, j;
    while( ~scanf("%d%d", &n, &m))
    {
        for(i = 0; i < n; i++)
            scanf("%d", &a[i]);
        getmin();
        getmax();
    }
    return 0;
}

 

posted @ 2012-10-04 22:00  To be an ACMan  Views(412)  Comments(0)    收藏  举报