题目链接:http://acm.nuc.edu.cn/problem/show/1926
题意:对一个队列进行插入和删除操作,然后会有询问最大值和最小值。
思路:开两个栈A,B,一个用来进一个用来出。然后分别在A,B这边维护最大值和最小值的两个栈。总共开了6个栈数组。
注意为了维护是队列的性质。当B为空的时候A才能吧它的元素放入其中。然后对每次出栈,入栈操作维护一下最大值最小值就行了。
(盗两张图,图转载自:http://www.yalewoo.com/queue_findmax.html)
PS:还是手动维护栈吧,用的stl会超时。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 10;
#define INF 0x3f3f3f3f
int A[maxn],B[maxn];
int max1[maxn],max2[maxn],min1[maxn],min2[maxn];
char s[20];
int main()
{
int n;
int T = 1;
while( ~ scanf("%d",&n) && n)
{
printf("Case %d:\n",T ++);
int top1 = 0,top2 = 0;
int top3 = 0,top4 = 0,top5 = 0,top6 = 0;
for(int i = 1; i <= n;i ++)
{
scanf("%s",s);
if(s[0] == 'E')
{
int x;scanf("%d",&x);
A[++ top1] = x;
if(!top3 || x >= max1[top3])max1[++ top3] = x;if(!top4 || x <= min1[top4])min1[++ top4] = x;
}
else if(s[0] == 'D')
{
if(!top2)
{
while(top1)
{
int x = A[top1];
B[++ top2] = A[top1 --];
if(max1[top3] == x)top3 --;if(min1[top4] == x)top4 --;
if(!top5 || x >= max2[top5])max2[++ top5] = x;
if(!top6 || x <= min2[top6])min2[++ top6] = x;
}
}
if(top2 == 0)
puts("EMPTY!");
else
{
int x = B[top2 --];
if(x == max2[top5])top5 --;
if(x == min2[top6])top6 --;
printf("%d\n",x);
}
}
else if(s[1] == 'A')
{
if(!top1 && !top2)
puts("EMPTY!");
else
{
printf("%d\n",max(!top3 ? 0 : max1[top3],!top5 ? 0 : max2[top5]) );
}
}
else if(s[1] == 'I')
{
if(!top1 && !top2)
puts("EMPTY!");
else
printf("%d\n",min(!top4 ? INF : min1[top4],!top6 ? INF : min2[top6]));
}
}
}
return 0;
}