题目:http://acm.hdu.edu.cn/showproblem.php?pid=5929
题意:
维护一个栈,支持往栈里塞 0/1 ,弹栈顶,翻转栈,询问从栈顶到栈底按顺序 NAND 的值。
分析:
【题解】只要知道最后的 000 后面 111 的个数的奇偶性就行。可以用链表把所有 000 的位置存下来。
思路基本和题解一样,都是先把0的位置保存起来,然后做相应的判断
这题的关键是怎么快速的求出从栈顶到栈底的与非值
∙ 0 nand 0 = 1
∙ 0 nand 1 = 1
∙ 1 nand 0 = 1
∙ 1 nand 1 = 0
可以看出任何数跟0的与非值都是1,所以只要知道最后一个0位置就行了,因为前面所有数到0后与非值都是1,这样再看一下0后面有几个1就行了。
数组模拟一下即可。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 4e5+10;
int a[N];
char op[11];
int main() {
//freopen("f.txt","r",stdin);
int n,x,T;
scanf("%d",&T);
for(int cas=1; cas<=T; cas++) {
scanf("%d",&n);
printf("Case #%d:\n",cas);
int cl=2e5+1,cr=2e5,l=cl,r=cr;
memset(a,-1,sizeof(-1));
int flag=1; //1往右走,0往左走
while(n--) {
scanf("%s",op);
if(op[0]=='P') {
if(op[1]=='O') { //pop
if(flag) {
--cr;
if(~a[r]&&a[r]>cr)--r;
} else {
++cl;
if(~a[l]&&a[l]<cl)++l;
}
} else { //push
scanf("%d",&x);
if(flag) {
if(x==0)a[++r]=++cr;
else ++cr;
} else {
if(x==0)a[--l]=--cl;
else --cl;
}
}
} else if(op[0]=='Q') { //query
if(cr<cl)puts("Invalid.");
else if(r<l) {
if((cr-cl+1)&1)puts("1");
else puts("0");
} else if(flag) {
if(a[l]==cr) {
if((a[l]-cl+1)&1)puts("0");
else puts("1");
} else if((a[l]-cl+1)&1)puts("1");
else puts("0");
} else {
if(a[r]==cl) {
if((cr-a[r]+1)&1)puts("0");
else puts("1");
} else if((cr-a[r]+1)&1)puts("1");
else puts("0");
}
} else flag^=1; //reverse
}
}
return 0;
}