标签:
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5929
要求模拟一个存入0,1的栈,有4个操作
1:push a,在栈顶插入a。
2:pop,删除栈顶。
3:reverse,将这个栈翻转一下(注意:这里一旦换位置,其输入的位置也要换的)。
4:query,询问栈顶到栈底的atop nand atop-1 nand ... a1。
题解:
我自己是用数组模拟双端队列的方式来做的。
其实其他的几个步骤都是比较简单实现的。就是求和的时候比较坑,常规的方法是不行的,预处理也不行。但是通过分析数据可以找到一个比较明显的规律,直接找离最后位置最近的0的位置,然后再找0之后1的个数,个数奇值为1,个数偶为值0,就行了。
代码:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
const int maxn = 2*1e5;
#define met(a,b) memset(a,b,sizeof(a))
char s[4][10]={"PUSH","POP","REVERSE","QUERY"};
ll num[2*maxn];
int main()
{
int t;
ll k=1;
scanf("%d",&t);
while(t--)
{
ll n;
scanf("%lld",&n);
printf("Case #%lld:\n",k++);
ll len=0;
ll flag=1;
ll num1=-inf,num2=inf;
ll l=maxn,r=maxn-1;
for(ll i=0;i<n;i++)
{
char s1[10];
scanf("%s",s1);
if(strcmp(s[0],s1)==0)
{
ll x,pos;
scanf("%lld",&x);
if(flag)
{
num[++r]=x;
pos=r;
}
else
{
num[--l]=x;
pos=l;
}
len++;
if(x==0)
{
num1=max(num1,pos);
num2=min(num2,pos);
}
}
if(strcmp(s[1],s1)==0)
{
if(flag)
r--;
else
l++;
len--;
}
if(strcmp(s[2],s1)==0)
{
flag^=1;
}
if(strcmp(s[3],s1)==0)
{
if(len<=0)
{
printf("Invalid.\n");
continue;
}
else
{
if(num1==-inf&&num2==inf)
{
ll len=r-l+1;
if(len&1)
printf("1\n");
else
printf("0\n");
continue;
}
if(flag)
{
ll ling=min(num1,num2);
ll len=ling-l+1;
if(ling==r)
len--;
if(len&1)
printf("1\n");
else
printf("0\n");
}
else
{
ll ling=max(num1,num2);
ll len=r-ling+1;
if(ling==l)
len--;
if(len&1)
printf("1\n");
else
printf("0\n");
}
}
}
}
}
}
2016CCPC东北地区大学生程序设计竞赛 - 重现赛 1008(hdu 5929)
标签:
原文地址:http://www.cnblogs.com/TAT1122/p/5935080.html