poj2823_Sliding WindowCrawling in process...
Crawling failed
Time Limit:12000MS
Memory Limit:65536KB 64bit IO Format:%I64d & %I64u
Description
An array of size n ≤ 10
6 is given to you. There is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the
k numbers in the window. Each time the sliding window moves rightwards by one position. Following is an example:
The array is [1 3 -1 -3 5 3 6 7], and
k is 3.
Window position |
Minimum value |
Maximum value |
---|
[1 3 -1] -3 5 3 6 7 |
-1 |
3 |
1 [3 -1 -3] 5 3 6 7 |
-3 |
3 |
1 3 [-1 -3 5] 3 6 7 |
-3 |
5 |
1 3 -1 [-3 5 3] 6 7 |
-3 |
5 |
1 3 -1 -3 [5 3 6] 7 |
3 |
6 |
1 3 -1 -3 5 [3 6 7] |
3 |
7 |
Your task is to determine the maximum and minimum values in the sliding window at each position.
Output
There are two lines in the output. The first line gives the minimum values in the window at each position, from left to right, respectively. The second line gives the maximum values.
Sample Output
-1 -3 -3 -3 3 3
3 3 5 5 6 7
題意:
給你一個長度不超過10 6 的數組,有一個長度爲k的滑動窗口從數組的最左邊依次移動到最右邊,找出每次移動後整個窗口裏面的最大值和最小值
解析:
這是一道典型的單調隊列,先給它用降序排一次,隊列的第一個數就是每次移動後的最大值,同理,升序排一次可以得到最小值。不過這道題有點坑,不能用G++提交,因爲那樣必須超時,但換成C++就能過(李博學長解釋是由於C++用的是WINDOWS的編譯器,對輸入輸出有優化的,但是G++沒有優化。)
#include<iostream>
#include<cstdio>
using namespace std;
int w[1000006],q[1000006],p[1000006];
int dow[1000006],up[1000006],p1,p2,q1,q2;
int main()
{
int n,k,minx,i;
scanf("%d %d",&n,&k);
p1=p2=q1=q2=1;
for(i=1;i<=n;i++)
{
scanf("%d",&w[i]);
while(p1<p2&&w[i]<=w[p[p2-1]])//形成一個單調遞增隊列
p2--;//w[p[p1]]最小
p[p2++]=i;//入隊
while(q1<q2&&w[i]>=w[q[q2-1]])//形成一個單調遞減數列,注意是q2-1
q2--;
q[q2++]=i;//q2-1的原因
if(i-p[p1]>=k) p1++;
if(i-q[q1]>=k) q1++;
if(i>=k)
{
dow[i]=w[p[p1]];
up[i]=w[q[q1]];
printf("%d ",dow[i]);
}
}
//for(i=k;i<n;i++)
// printf("%d ",dow[i]);
printf("\n");
for(i=k;i<n;i++)
printf("%d ",up[i]);
printf("%d\n",up[i]);
return 0;
}