题意:给一个栈,有push , pop , reverse , query 。 query求从栈顶到栈底逐个求 NAND 的值, 如果栈为空就输出 Invalid.
解法:可以用双向队列来模拟操作,每次都记录最接近栈底的0的位置(两边都要),那么对于QUERY操作,如果存在0位置,如果在0之前有数字,那么到0这个位置就会变成1, 不然就是0。然后从0的位置往后一定都是1,对于每一个1,答案都会取反一次,所以就相当于数一下1的个数奇偶情况就可以了。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <iostream>
using namespace std;
const int maxn = 600000;
int a[maxn], len, head, tail, n, t, cnt, k;
int b[maxn], hh, tt;
char s[10];
int main() {
int T;
scanf("%d", &T);
for (int cases = 1; cases <= T; cases++) {
printf("Case #%d:\n", cases);
scanf("%d", &n);
memset(a, 0, sizeof(a));
head = tail = 300000;
hh = tt = 300000;
k = 1;
while (n--) {
scanf("%s", s);
len = strlen(s);
if (len == 4) {
scanf("%d", &t);
if (k == 1) {
a[tail] = t;
tail++;
if (t == 0) {
b[tt] = tail-1;
tt++;
}
} else {
head--;
a[head] = t;
if (t == 0) {
hh--;
b[hh] = head;
}
}
} else if (len == 3) {
if (k == 1) {
tail--;
if (a[tail] == 0) tt--;
} else {
if (a[head] == 0) hh++;
head++;
}
} else if (len == 7) {
k = -k;
} else if (len == 5) {
if (head == tail) {
printf("Invalid.\n");
} else {
if (k == 1) {
if (hh == tt) {
len = tail-head;
if (len%2 == 1) printf("1\n");
else printf("0\n");
} else {
len = b[hh]-head+1;
if (b[hh] == tail-1) len--;
if (len%2 == 1) printf("1\n");
else printf("0\n");
}
} else {
if (hh == tt) {
len = tail-head;
if (len%2 == 1) printf("1\n");
else printf("0\n");
} else {
len = tail-b[tt-1];
if (b[tt-1] == head) len--;
if (len%2 == 1) printf("1\n");
else printf("0\n");
}
}
}
}
}
}
}