UVa 112 - Tree Summing解题报告

来源:互联网 发布:炎黄网络 服务器怎么样 编辑:程序博客网 时间:2024/06/05 07:51

题意:

题目要求很简单,意思是要构造一颗二叉树,然后求出所有根结点到叶结点的路径上的数字之和,如果有一个是和题目所给的一样,那么输出yes,否则no

左括号‘(' 表示新建一个子结点, 优先建立左儿子,如果左儿子建立过了,则建立右儿子。 右括号表示退回父结点。如果一对括号内是空的,表示这个结点

也是空的。


思路:

输入比较复杂, 有括号,有数字,又有空格,于是用getchar()一个一个读, 过滤掉空格,保存到一个数组里。然后再处理。  然后利用栈建二叉树, 进行深搜,得到路径和。

另一个思路比较简单,题目给出的数据本身具备前序遍历的顺序,可以直接算路径和。但是我想熟悉一下建二叉树和深度搜索,所以用的是建树深搜的思路。

PS:下面代码有个小bug,如果只有一个叶子节点的情况下,建的二叉树都会把叶子作为左叶子。但是不影响结果。

//112 - Tree Summing#include <iostream>#include <cstring>#include <stack>using namespace std;struct Nobe{int value;Nobe *left = NULL, *right = NULL;bool haveleft = false;//判断是否已有右节点};char str[5200];void DFS(Nobe *, int, int);bool found;int main(){freopen("data.txt", "r", stdin);int sum;while (scanf("%d", &sum) != EOF){int bracket = 0, len = 0;char c;while ((c = getchar()) != '(');//跳过前面的空格str[len++] = c;//bracket++;while (bracket)//括号匹配就退出{while((c = getchar()) == ' ' || c == '\n');//跳过中间的空格和换行符if(c == '(')//bracket++;if(c == ')')bracket--;str[len++] = c;}if(str[0] == '(' && str[1] == ')')//如果是空树{printf("no\n");continue;}stack<Nobe*> st;int x;sscanf(&str[1], "%d", &x);//取出字符串中的数字Nobe *s = new Nobe;s->value = x;Nobe *root = s;//初始化根st.push(s);int i = 1;while (!st.empty()){while(str[i] != '(' && str[i] != ')')//跳过数字占用的字符i++;if(str[i] == '(' && str[i + 1] != ')')//排除"()"的情况{sscanf(&str[++i], "%d", &x);Nobe *s = new Nobe;s->value = x;st.push(s);}else if(str[i] == ')' && str[i - 1] != '(')//排除"()"的情况,出栈建树{Nobe *p;p = st.top();st.pop();if(!st.empty())if(!st.top()->haveleft)//{st.top()->left = p;st.top()->haveleft = true;}elsest.top()->right = p;}i++;}found = false;DFS(root, sum, 0);if(found)printf("yes\n");elseprintf("no\n");memset(str, 0, sizeof(str));}return 0;}void DFS(Nobe *s, int sum, int n){if(found)return;n += s->value;if(s->left == NULL && s->right == NULL){if(n == sum)found = true;return;}if(s->left)DFS(s->left, sum, n);if(s->right)DFS(s->right, sum, n);}


0 0
原创粉丝点击