http://acm.pku.edu.cn/JudgeOnline/problem?id=1460
没啥好说的,就是赤裸裸的表达式求值。先2^n枚举运算符,复杂度是O(2^n * len),len是表达式的长度。一开始以为是只有一个问号,结果wa了一次才发现是最多有10个问号……这次想练代码,所以没用STL,但是又有点偷懒,所以就复制粘贴了一些代码,而没写成函数……
1 #include <cstdio>
2
3 const int MAX_LEN = 110;
4 const int MAX_MARK = 11;
5 const char REPLACE[] = {'+', '-', '*', '/'};
6
7 template <class T>
8 class Stack {
9
10 private:
11 T base[MAX_LEN];
12 int tail;
13
14 public:
15 Stack() : tail(0) {}
16 void push(T x) {
17 base[tail++] = x;
18 }
19 T top() {
20 return base[tail - 1];
21 }
22 void pop() {
23 --tail;
24 }
25 bool empty() {
26 return !tail;
27 }
28
29 };
30
31 int mk[MAX_MARK];
32 char st1[MAX_LEN], st2[MAX_LEN * 2];
33 int cas, ret, marks;
34
35 int main() {
36 for (scanf("%d", &cas); cas; --cas) {
37 scanf("%s", st1);
38 scanf("%d", &ret);
39 marks = 0;
40 for (int i = 0; st1[i]; ++i)
41 if (st1[i] == '?') mk[marks++] = i;
42 bool flag = 0;
43 for (int k = 0; k < 1 << 2 * marks; ++k) {
44 for (int i = 0; i < marks; ++i) {
45 st1[mk[i]] = REPLACE[((k & 1 << i * 2) >= 1) * 2 + ((k & 1 << i * 2 + 1) >= 1)];
46 }
47 Stack <char> op;
48 int len = 0;
49 for (int i = 0; st1[i]; ++i) {
50 if (st1[i] >= '0' && st1[i] <= '9') {
51 while (st1[i] >= '0' && st1[i] <= '9') st2[len++] = st1[i++];
52 st2[len++] = ' ';
53 --i;
54 } else {
55 switch (st1[i]) {
56 case '+':
57 case '-':
58 while (!op.empty() && op.top() != '(') {
59 st2[len++] = op.top();
60 op.pop();
61 }
62 op.push(st1[i]);
63 break;
64 case '*':
65 case '/':
66 while (!op.empty() && (op.top() == '*' || op.top() == '/')) {
67 st2[len++] = op.top();
68 op.pop();
69 }
70 op.push(st1[i]);
71 break;
72 case '(':
73 op.push(st1[i]);
74 break;
75 case ')':
76 while (op.top() != '(') {
77 st2[len++] = op.top();
78 op.pop();
79 }
80 op.pop();
81 break;
82 }
83 }
84 }
85 Stack <int> num;
86 bool ok = 1;
87 for (int i = 0; ok && i < len; ++i) {
88 if (st2[i] >= '0' && st2[i] <= '9') {
89 int tmp = 0;
90 while (st2[i] >= '0' && st2[i] <= '9') tmp = tmp * 10 + st2[i++] - '0';
91 num.push(tmp);
92 } else {
93 int num1, num2;
94 switch (st2[i]) {
95 case '+':
96 num2 = num.top();
97 num.pop();
98 num1 = num.top();
99 num.pop();
100 num.push(num1 + num2);
101 break;
102 case '-':
103 num2 = num.top();
104 num.pop();
105 num1 = num.top();
106 num.pop();
107 num.push(num1 - num2);
108 break;
109 case '*':
110 num2 = num.top();
111 num.pop();
112 num1 = num.top();
113 num.pop();
114 num.push(num1 * num2);
115 break;
116 case '/':
117 num2 = num.top();
118 if (!num2) {
119 ok = 0;
120 break;
121 }
122 num.pop();
123 num1 = num.top();
124 num.pop();
125 num.push(num1 / num2);
126 break;
127 }
128 }
129 }
130 while (ok && !op.empty()) {
131 int num1, num2;
132 switch (op.top()) {
133 case '+':
134 num2 = num.top();
135 num.pop();
136 num1 = num.top();
137 num.pop();
138 num.push(num1 + num2);
139 break;
140 case '-':
141 num2 = num.top();
142 num.pop();
143 num1 = num.top();
144 num.pop();
145 num.push(num1 - num2);
146 break;
147 case '*':
148 num2 = num.top();
149 num.pop();
150 num1 = num.top();
151 num.pop();
152 num.push(num1 * num2);
153 break;
154 case '/':
155 num2 = num.top();
156 if (!num2) {
157 ok = 0;
158 break;
159 }
160 num.pop();
161 num1 = num.top();
162 num.pop();
163 num.push(num1 / num2);
164 break;
165 }
166 op.pop();
167 }
168 if (!ok) continue;
169 if (num.top() == ret) {
170 flag = 1;
171 puts("yes");
172 break;
173 }
174 }
175 if (!flag) puts("no");
176 }
177 return 0;
178 }
179