| Time Limit: 12000MS | Memory Limit: 65536K | |
| Total Submissions: 559348 | Accepted: 12040 | |
| Case Time Limit: 5000MS | ||
Description
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.
Input
Output
Sample Input
8 3 1 3 -1 -3 5 3 6 7
Sample Output
-1 -3 -3 -3 3 3
3 3 5 5 6 7
Source
题目大意:给一个长度为n的数组 ,和正整数k,然后依次从宽度(数的个数)为k的子组中找出最大值
//单调队列
#include<cstdio>
#include<queue>
using namespace std;
const int N=1e6;
int a[N+10],ma[N+10],mi[N+10];
int h[N+10],q[N+10];
int n,k;
void getmax()
{
int i,head=1,tail=0;
for( i=1;i<k;i++)
{
while(head<=tail&&h[tail]<a[i])//关键
tail--;
tail++;
h[tail]=a[i];
q[tail]=i;
}
for( i=k;i<=n;i++)
{
while(head<=tail&&h[tail]<a[i])
tail--;
tail++;
h[tail]=a[i];
q[tail]=i;
while(q[head]<=i-k)head++;
ma[i-k+1]=h[head];
}
}
void getmin()
{
int i,head=1,tail=0;
for( i=1;i<k;i++)
{
while(head<=tail&&h[tail]>a[i])
tail--;
tail++;
h[tail]=a[i];
q[tail]=i;
}
for( i=k;i<=n;i++)
{
while(head<=tail&&h[tail]>a[i])
tail--;
tail++;
h[tail]=a[i];
q[tail]=i;
while(q[head]<=i-k)head++;
mi[i-k+1]=h[head];
}
}
int main()
{
while(~scanf("%d%d",&n,&k))
{
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
getmax();
getmin();
int aa=n-k+1;
for(int i=1;i<aa;i++)
printf("%d ",mi[i]);
printf("%d\n",mi[aa]);
for(int i=1;i<aa;i++)
printf("%d ",ma[i]);
printf("%d\n",ma[aa]);
}
return 0;
}
优先队列的巧用 同理用堆也能写
//优先队列 注意用G++提交会超时 用C++提交可以过
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
const int N=1e6;
int a[N+10],ma[N+10],mi[N+10];//分别储存 原始数据 和 区间最大值 最小值
struct cmp1
{
bool operator()(const int a1,const int a2)
{
return a[a1]>a[a2]; //越小越优先
}
};
struct cmp2
{
bool operator()(const int a1,const int a2)
{
return a[a1]<a[a2];
}
};
int main()
{ int n,k;
while(cin>>n>>k)
{
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
priority_queue<int,vector<int>,cmp1> q;
priority_queue<int,vector<int>,cmp2> p;
for(int i=1;i<=k;i++)
{
q.push(i);
p.push(i);
}
int aa=0,ii=0;
mi[++ii]=a[q.top()];
ma[++aa]=a[p.top()];
for(int i=k+1;i<=n;i++)
{ int j=i-k;
q.push(i);
p.push(i);
while(i-q.top()>=k)
q.pop(); //pop()踢出当前最值
while(i-p.top()>=k)
p.pop();
mi[++ii]=a[q.top()];
ma[++aa]=a[p.top()];
}
for(int i=1;i<aa;i++)
printf("%d ",mi[i]);
printf("%d\n",mi[aa]);
for(int i=1;i<aa;i++)
printf("%d ",ma[i]);
printf("%d\n",ma[aa]);
}
return 0;
}