https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=48
题目描述
Lisp是最早的高级编程语言之一,Fortran是现在还在用的最古老的语言之一(说得好像Lisp不是一样)。序列是Lisp语言的基础的数据结构,可以很容易地导出其他数据结构,比如树。
本题需要你解决用Lisp的S表达式表示的二叉树。给定一个带权的二叉树,写一个程序判断是否存在从根到叶子节点的一条简单路径,使得路径上的节点的权值和恰好为某一个特别的数字
k
。比如下图中存在4条这样的路径,权值和分别为27,22,26,18。
输入数据中用Lisp的S表达式表示的二叉树形式如下:
empty_tree ::= ()
tree ::= empty_tree | (integer tree tree)
上图的二叉树用S表达式表示的结果为:(5 (4 (11 (7 () ()) (2 () ()) ) ()) (8 (13 () ()) (4 () (1 () ()) ) ) )
。
注意叶子结点的表示方法为:(integer () ())
。
输入
输入包含多组测试数据,每组数据不定行数,第一个数字
输出
每组数据输出一行”yes”或者”no”,表示是否存在一条符合要求的路径其权值和恰好为 k <script type="math/tex" id="MathJax-Element-328">k</script>。
输入样例
22 (5(4(11(7()())(2()()))()) (8(13()())(4()(1()()))))
20 (5(4(11(7()())(2()()))()) (8(13()())(4()(1()()))))
10 (3
(2 (4 () () )
(8 () () ) )
(1 (6 () () )
(4 () () ) ) )
5 ()
输出样例
yes
no
yes
no
题解
本题大概只是字符串处理有点麻烦。
一个’(‘表示一个树开始描述,然后我们读入一个数字表示该节点的权值。接着递归遍历两个子树,如果都为空,则该节点为叶子结点,判断路径权值和。然后就会读到’)’。
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 1024;
int l[N], r[N], sum, ans;
bool dfs(int s) {
int val; bool flag = true;
while (getchar() != '(');
if (scanf("%d", &val) == 1) {
bool l = dfs(s + val);
bool r = dfs(s + val);
if (!l && !r && s + val == sum)
ans = true;
} else flag = false;
while (getchar() != ')');
return flag;
}
int main() {
while (scanf("%d", &sum) != EOF) {
ans = false;
dfs(0);
puts(ans ? "yes" : "no");
}
return 0;
}