HDU 5929 Basic Data Structure【模拟】【deque】

题目大意:

现有一个栈,请你对它做出如下操作:

  1. PUSH x:将元素x入栈。
  2. POP:将栈顶元素出栈。
  3. REVERSE:将栈内元素翻转。
  4. QUERY:查询从栈顶元素开始到栈底元素的NAND和。

其中NAND的定义为:

  • 0 nand 0 = 1
  • 0 nand 1 = 1
  • 1 nand 0 = 1
  • 1 nand 1 = 0

解题思路:

对于操作1和操作2直接模拟就好了,费时的部分是剩余的两个操作。

考虑到n的范围最大取值为200000,我们可以开个400000的数组,取中间部分为初始起点,当进行操作3的时候直接将头对另一边进行1、2操作就好了。

观察这个nand运算我们发现,只要和0进行运算的,答案都变成了1,利用这一点我们可以记录0出现的位置,就是出现了0就将它存起来。我们可以也像上面那样进行记录,出于好写我这里直接用的deque。这样,每当查询时我们直接看存起来的0的位置,如果没有0那就数1的个数;如果有的话就看从头开始最后一个出现的0之后有多少个1。这里有个细节要注意,就是当只有1个0的时候,要特别判断一下。

Mycode:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <deque>
using namespace std;
const int N = 200010;

char op[11];
int t, n, x, rig, lef, a[N<<1];
int main()
{
scanf("%d", &t);
for(int cas = 1; cas <= t; ++cas)
{
deque<int> Q;
rig = 200001;
lef = rig - 1;
bool flag = true;
printf("Case #%d:\n", cas);

scanf("%d", &n);
while(n--)
{
scanf("%s", op);
if(op[0] == 'P')
{
if(op[1] == 'U')
{
scanf("%d", &x);
if(flag)
{
if(!x) Q.push_back(rig);
a[rig++] = x;
}
else
{
if(!x) Q.push_front(lef);
a[lef--] = x;
}
}
else
{
if(flag)
{
--rig;
if(!a[rig]) Q.pop_back();
}
else
{
++lef;
if(!a[lef]) Q.pop_front();
}
}
}

if(op[0] == 'Q')
{
if(lef + 1 == rig)
puts("Invalid.");
else if(Q.empty())
printf("%d\n", (rig - lef - 1) & 1);
else
{
if(flag)
{
printf("%d\n", ((Q.front() - lef - 1) +(rig - 1 != Q.front())) & 1);
}
else
{
printf("%d\n", ((rig - Q.back() - 1) +(lef + 1 != Q.back())) & 1);
}
}
}

if(op[0] == 'R')
{
flag = !flag;
}
}
}
return 0;
}
Donate comment here
0%