题意:类似于括号匹配, 不过每个数字只能跟自己的相反数匹配。并且, 括号的所有直接子括号的数值之和必须小于它的数值。
思路:用栈模拟, 遇到负数入栈; 正数则与栈顶匹配, 若匹配成功则消去栈顶 , 否则也入栈。栈的元素是结构体, 除了上面的括号自身的数值value外, 还有所有直接子括号的和sum。 在负数入栈前, 要把它的数值加到栈顶(如果empty就不用)的sum, 并判断, 判断完才能入栈。
算法复杂度:n个括号 操作n次。 所以是o(N)。
代码:
#include <cstdio>
#include <stack>
using namespace std;
struct Num
{
int value;
int childSum;
};
stack<Num> sta;
bool ok;
int value;
char ch;
void init();
void doOnce();
bool judge();
int main()
{
init();
while (scanf("%d%c", &value, &ch) == 2) {
if (ch == '\n') {
doOnce();
if (judge()) {
printf(":-) Matrioshka!\n");
} else {
printf(":-( Try again.\n");
}
init();
} else {
doOnce();
}
}
return 0;
}
void init()
{
while (!sta.empty()) {
sta.pop();
}
ok = true;
}
void doOnce()
{
Num tp;
tp.value = value;
tp.childSum = 0;
if (value < 0) {
if (sta.empty()) {
sta.push(tp);
} else {
sta.top().childSum += tp.value;
if (sta.top().childSum <= sta.top().value) {
ok = false;
}
sta.push(tp);
}
} else {
if (sta.empty()) {
ok = false;
} else if (sta.top().value == -tp.value) {
sta.pop();
} else {
sta.push(tp);
}
}
}
bool judge()
{
if (ok && sta.empty()) {
return true;
} else {
return false;
}
}