此处为栈和队列的专题
A - Train Problem I
B - 简单计算器
C - Team Queue
D - 愚人节的礼物
E - ACboy needs your help again!
F - 看病要排队
G - Windows Message Queue
思路:模板题,就是自己在本子上模拟即可(或者去B站搜搜视频)
这题刚好取两个极限,一个最大一个最小
#include<iostream>
const int N = 1e6+10;
int a[N],q[N];
int n,m;
using namespace std;
int main()
{
cin>>n>>m;
for(int i = 1;i <= n;i++)
{
cin>>a[i];
}
int h = 0,t = -1;
for(int i = 1;i <= n;i++)
{
while(h <= t && a[i] <= a[q[t]]) t--;
q[++t] = i;
if(h <= t && q[h] < i-m+1)h++;
if(i > m-1)cout<<a[q[h]]<<" ";
}
cout<<endl;
h = 0,t = -1;
for(int i = 1;i <= n;i++)
{
while(h <= t && a[i] >= a[q[t]])t--;
q[++t] = i;
if(h <= t && q[h] < i-m+1)h++;
if(i > m-1)cout<<a[q[h]]<<" ";;
}
return 0;
}
思路:一个单调队列即可
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e6+10;
int q[N];
int ans = 0x3f3f3f;
int n,m;
struct node
{
int x,y;
}a[N];
bool cmp(node x,node y)
{
return x.x < y.x;
}
int main()
{
int ma = 0,mi = 0x3f3f3f;
cin>>n>>m;
for(int i = 1;i <= n;i++)
{
cin>>a[i].x>>a[i].y;
ma = max(ma,a[i].y);
mi = min(mi,a[i].y);
}
sort(a+1,a+n+1,cmp);
int h = 1,t = 0;
for(int i = 1;i <= n;i++)
{
while(h <= t && a[i].y <= a[q[t]].y) t--;
q[++t] = i;
while(h <= t && a[q[t]].y - a[q[h]].y >= m)ans = min(ans,a[q[t]].x - a[q[h]].x),h++;
}
if(ans == 0x3f3f3f)cout<<"-1"<<endl;
else cout<<ans<<endl;
return 0;
}
思路:继续单调队列模拟即可
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int N = 1e6+10;
struct zz
{
int a,b;
}d[N],q[N];
int a[N];
int cnt;//用来记录每一次的珠子颜色
int minn = 0x3f3f3f3f,x,num;
int n,k;
inline bool cmp(zz x,zz y)
{
return x.a < y.a;
}
int main()
{
cin>>n>>k;
for(int i = 1;i <= k;i++)
{
cin>>x;
for(int j = 1;j <= x;j++)
{
cin>>d[++num].a;
d[num].b = i;
}
}
int h = 1,t = 0;
sort(d+1,d+num+1,cmp);
for(int i = 1;i <= n;i++)
{
q[++t] = d[i];
a[d[i].b]++;
if(a[d[i].b] == 1)cnt++;
while(cnt == k)
{
minn = min(minn,q[t].a - q[h].a);
a[q[h].b]--;
if(a[q[h].b] == 0)cnt--;
h++;
}
}
cout<<minn<<endl;
return 0;
}