poj2823
题意:给定一个数列,从左至右输出每个长度为m的数列段内的最小数和最大数。
分析:在这里我们以求最大值为例,最小值同理。用单调双向队列来做,动态规划。从左到右把窗户推一便,每推一格,就把新来的元素入队,入队过程中先把队尾小于它的元素全去掉(因为这些值不可能成为窗子区间内的最大值了),再把它加到队尾。这样就保证了队列中元素是单调递减的。还要注意及时把不在窗户区间内的队首元素弹出。每次要取窗子区间内的最大值,只需看队首元素即可。
View Code
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
usingnamespace std;
#define maxn 1000005
struct Item
{
int value, index;
} q[maxn], f[maxn];
int n, k, head, tail;
void ins1(Item &a)
{
while (head != tail && q[tail -1].value >= a.value)
{
tail--;
if (tail <0)
tail += maxn;
}
q[tail++] = a;
if (tail >= maxn)
tail =0;
if (a.index - q[head].index >= k)
head++;
if (head >= maxn)
head =0;
}
void ins2(Item &a)
{
while (head != tail && q[tail -1].value <= a.value)
{
tail--;
if (tail <0)
tail += maxn;
}
q[tail++] = a;
if (tail >= maxn)
tail =0;
if (a.index - q[head].index >= k)
head++;
if (head >= maxn)
head =0;
}
int main()
{
//freopen("D:\\t.txt", "r", stdin);
scanf("%d%d", &n, &k);
for (int i =0; i < n; i++)
{
scanf("%d", &f[i].value);
f[i].index = i;
}
for (int i =0; i < k -1; i++)
ins1(f[i]);
for (int i = k -1; i < n; i++)
{
ins1(f[i]);
printf("%d", q[head].value);
if (i != n -1)
printf("");
}
printf("\n");
head =0;
tail =0;
for (int i =0; i < k -1; i++)
ins2(f[i]);
for (int i = k -1; i < n; i++)
{
ins2(f[i]);
printf("%d", q[head].value);
if (i != n -1)
printf("");
}
return0;
}
#include <cstdlib>
#include <cstring>
#include <cstdio>
usingnamespace std;
#define maxn 1000005
struct Item
{
int value, index;
} q[maxn], f[maxn];
int n, k, head, tail;
void ins1(Item &a)
{
while (head != tail && q[tail -1].value >= a.value)
{
tail--;
if (tail <0)
tail += maxn;
}
q[tail++] = a;
if (tail >= maxn)
tail =0;
if (a.index - q[head].index >= k)
head++;
if (head >= maxn)
head =0;
}
void ins2(Item &a)
{
while (head != tail && q[tail -1].value <= a.value)
{
tail--;
if (tail <0)
tail += maxn;
}
q[tail++] = a;
if (tail >= maxn)
tail =0;
if (a.index - q[head].index >= k)
head++;
if (head >= maxn)
head =0;
}
int main()
{
//freopen("D:\\t.txt", "r", stdin);
scanf("%d%d", &n, &k);
for (int i =0; i < n; i++)
{
scanf("%d", &f[i].value);
f[i].index = i;
}
for (int i =0; i < k -1; i++)
ins1(f[i]);
for (int i = k -1; i < n; i++)
{
ins1(f[i]);
printf("%d", q[head].value);
if (i != n -1)
printf("");
}
printf("\n");
head =0;
tail =0;
for (int i =0; i < k -1; i++)
ins2(f[i]);
for (int i = k -1; i < n; i++)
{
ins2(f[i]);
printf("%d", q[head].value);
if (i != n -1)
printf("");
}
return0;
}