标签:
题目链接:
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