题目大意:
给 1 - n 的数字,在其中添加 {'+', '-', ' '},使其最终值为0
思路很简单,
因为 n <= 9, 所以可以dfs先生成所有可能的情况组合
然后对于每个组合去判断值是否为 0
因为感觉空格稍稍有点麻烦(...),就用了栈,还是挺轻松就搞定了的
AC代码如下:
/*
PROB: zerosum
LANG: C++
ID: fan_0111
*/
#include <iostream>
#include <stack>
#include <cstdio>
using namespace std;
char ch[3] = {' ', '+', '-'};
int a[110], n;
stack<int> digit;
stack<char> sign;
bool check() {
while (!digit.empty()) digit.pop();
while (!sign.empty()) sign.pop();
for (int i = 0; i < 2*n; ++i) {
if (a[i] >= 1 && a[i] <= n) { digit.push(a[i]); continue; }
if (a[i] == ' ') {
if (!sign.empty() && sign.top() == ' ') {
int x2 = digit.top(); digit.pop();
int x1 = digit.top(); digit.pop();
sign.pop();
digit.push(x1*10 + x2);
}
sign.push(a[i]);
continue;
}
while (!sign.empty()) {
int x2 = digit.top(); digit.pop();
int x1 = digit.top(); digit.pop();
int si = sign.top(); sign.pop();
switch (si) {
case '+': digit.push(x1 + x2); break;
case '-': digit.push(x1 - x2); break;
case ' ': digit.push(x1*10 + x2); break;
}
}
sign.push(a[i]);
}
return digit.top() == 0;
}
void print() {
for (int i = 0; i < 2*n-1; ++i) {
if (i & 1) cout << (char)a[i];
else cout << a[i];
}
cout << endl;
}
void dfs(int dep) {
if (dep == n-1) {
if (check()) print();
return;
}
for (int i = 0; i < 3; ++i) {
a[2*dep+1] = ch[i];
dfs(dep+1);
}
}
int main() {
freopen("zerosum.in", "r", stdin);
freopen("zerosum.out", "w", stdout);
cin >> n;
for (int i = 1; i <= n; ++i) {
a[i*2-2] = i;
}
a[2*n-1] = '+';
dfs(0);
fclose(stdin);
fclose(stdout);
return 0;
}
但是事实上,后来看 ANALYSIS, 里面的判断是否为 0 的做法还是挺普通的...虽然 switch 用得很好看就是了
不知道我当时为什么没想到...
再看看自己的栈,还是写的挺丑的
ANALYSIS 部分代码如下:
int
eval(char *s)
{
int term, sign, sum;
char *p;
sign = 1;
term = 0;
sum = 0;
for(p=s; *p; p++) {
switch(*p){
case '+':
case '-':
sum += sign*term;
term = 0;
sign = *p == '+' ? 1 : -1;
break;
case ' ':
break;
default: /* digit */
term = term*10 + *p-'0';
}
}
sum += sign*term;
return sum;
}