Tree Summing
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 7698   Accepted: 1737

Description

LISP was one of the earliest high-level programming languages and, with FORTRAN, is one of the oldest languages currently being used. Lists, which are the fundamental data structures in LISP, can easily be adapted to represent other important data structures such as trees.

This problem deals with determining whether binary trees represented as LISP S-expressions possess a certain property. 
Given a binary tree of integers, you are to write a program that determines whether there exists a root-to-leaf path whose nodes sum to a specified integer. For example, in the tree shown below there are exactly four root-to-leaf paths. The sums of the paths are 27, 22, 26, and 18. 

Binary trees are represented in the input file as LISP S-expressions having the following form.

empty tree ::= ()

tree 	   ::= empty tree (integer tree tree)

The tree diagrammed above is represented by the expression (5 (4 (11 (7 () ()) (2 () ()) ) ()) (8 (13 () ()) (4 () (1 () ()) ) ) )

Note that with this formulation all leaves of a tree are of the form (integer () () )

Since an empty tree has no root-to-leaf paths, any query as to whether a path exists whose sum is a specified integer in an empty tree must be answered negatively.

Input

The input consists of a sequence of test cases in the form of integer/tree pairs. Each test case consists of an integer followed by one or more spaces followed by a binary tree formatted as an S-expression as described above. All binary tree S-expressions will be valid, but expressions may be spread over several lines and may contain spaces. There will be one or more test cases in an input file, and input is terminated by end-of-file.

Output

There should be one line of output for each test case (integer/tree pair) in the input file. For each pair I,T (I represents the integer, T represents the tree) the output is the string yes if there is a root-to-leaf path in T whose sum is I and no if there is no path in T whose sum is I.

Sample Input

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 ()

Sample Output

yes
no
yes
no
题目大意:输入一个整数sum,后面是一串字符,代表一颗二叉树,二叉树结点类型为(integer () () ),问是否存在一条从根节点到叶子节点的路径上数字之和为sum.
解题方法:先通过字符串构造一颗二叉树,然后通过二叉树的非递归后序遍历判断是否存在解,这道题费了我九牛二虎之力,终于AC了。
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std; char str[]; typedef struct node
{
int data;
node *lchild;
node *rchild;
bool bleftvisted;//用于标记左孩子是否访问过
node()
{
lchild = rchild = NULL;
bleftvisted = false;
}
}TreeNode; //删除二叉树
void DeleteNode(TreeNode *pRoot)
{
if (pRoot != NULL)
{
DeleteNode(pRoot->lchild);
DeleteNode(pRoot->rchild);
}
delete pRoot;
} //创建一颗二叉树
void CreateTree(TreeNode *&pRoot)
{
TreeNode *StackNode[], *p;//StackNode为保存二叉树节点的栈
char StackCh[];//保存字符的栈
int topnode = -, topch = -, num, flag = , j = ;
bool isnum = false;
char ch;
num = ;
isnum = false ;
while(str[j] != '\0')
{
ch = str[j];
switch(ch)
{
case ')'://如果是右括号则把相应配对的左括号和他们之间的数字出栈
{
bool bflag = false;
while(StackCh[topch] != '(')
{
//如果遇见了数字,则必须让保存二叉树节点的栈退栈,
//表明该节点已经构造完了
if (isdigit(StackCh[topch]))
{
bflag = true;
}
--topch;
}
if (bflag)
{
--topnode;
}
j++;
--topch;
//如果某个节点的左孩子节点为空,则把左孩子访问标记为true
if (topnode >= )
{
StackNode[topnode]->bleftvisted = true;
}
break;
}
case '('://遇到左括号,直接入栈
StackCh[++topch] = ch;
j++;
break;
case '-':
flag = -;
j++;
break;
default://遇到数字,新建一个节点,然后插入到相应的位置
num = num * + (ch - '');
StackCh[++topch] = ch;
while(isdigit(ch = str[++j]))
{
num = num * + (ch - '');
StackCh[++topch] = ch;
}
p = new TreeNode;
p->data = num * flag;
flag = ;
num = ;
if (pRoot == NULL)//如果根节点为空,则把新节点赋给根节点
{
pRoot = p;
}
else
{
//如果左孩子节点未被访问,则先插入左孩子节点
if (StackNode[topnode]->bleftvisted == false)
{
StackNode[topnode]->lchild = p;
StackNode[topnode]->bleftvisted = true;
}
else//否则插入到右孩子节点
{
StackNode[topnode]->rchild = p;
}
}
StackNode[++topnode] = p;//新节点入栈
break;
}
}
} //二叉树的非递归后序遍历查找是否满足条件
bool Postorder(TreeNode *pRoot, int sum)
{
TreeNode *Stack[];
int top = -;
TreeNode *p = pRoot, *q;
if (pRoot != NULL)
{
do
{
while(p != NULL)
{
Stack[++top] = p;
p = p->lchild;
}
q = NULL;
while(top != -)
{
p = Stack[top];
//如果q == NULL则表示p的右孩子不存在,而左子树不存在或者已经访问,所以可以访问p节点,
//如果q != NULL则表示p的右子树已经被访问了,所以访问p节点
if (q == p->rchild)
{
if (p->lchild == NULL && p->rchild == NULL)
{
int temp = ;
//因为在后序遍历中,栈中保存的节点即为当前节点和它的所有父节点,
//所以便利一遍相加所得的和就是根节点到当前节点路径上所有节点之和
for (int i = ; i <= top; i++)
{
temp += Stack[i]->data;
}
if (temp == sum)
{
return true;
}
}
top--;
q = p;
}
else
{
p = p->rchild;
break;
}
}
} while (top != -);
}
return false;
} int main()
{
int sum;
while(scanf("%d", &sum) != EOF)
{
TreeNode *pRoot = NULL;
char ch;
int nCount = -;
while ((ch = getchar()) != '(');
str[++nCount] = ch;
int mark = ;
while(mark != )
{
ch = getchar();
switch(ch)
{
case ')':
mark--;
str[++nCount] = ch;
break;
case '(':
mark++;
str[++nCount] = ch;
break;
case '-':
str[++nCount] = ch;
break;
case ' ':
break;
case '\0':
break;
case '\n':
break;
default:
str[++nCount] = ch;
break;
}
}
str[nCount + ] = '\0';
CreateTree(pRoot);
if (pRoot == NULL)
{
printf("no\n");
continue;
}
if (Postorder(pRoot, sum))
{
printf("yes\n");
}
else
{
printf("no\n");
}
DeleteNode(pRoot);
}
return ;
}
												

POJ 1145 Tree Summing的更多相关文章

  1. POJ 题目1145/UVA题目112 Tree Summing(二叉树遍历)

    Tree Summing Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8132   Accepted: 1949 Desc ...

  2. UVa 112 - Tree Summing(树的各路径求和,递归)

    题目来源:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=3&pa ...

  3. poj 3237 Tree [LCA] (树链剖分)

    poj 3237 tree inline : 1. inline 定义的类的内联函数,函数的代码被放入符号表中,在使用时直接进行替换,(像宏一样展开),没有了调用的开销,效率也很高. 2. 很明显,类 ...

  4. poj 3237 Tree(树链拆分)

    题目链接:poj 3237 Tree 题目大意:给定一棵树,三种操作: CHANGE i v:将i节点权值变为v NEGATE a b:将ab路径上全部节点的权值变为相反数 QUERY a b:查询a ...

  5. POJ 1741 Tree 求树上路径小于k的点对个数)

                                                                                                 POJ 174 ...

  6. POJ 2378 Tree Cutting 3140 Contestants Division (简单树形dp)

    POJ 2378 Tree Cutting:题意 求删除哪些单点后产生的森林中的每一棵树的大小都小于等于原树大小的一半 #include<cstdio> #include<cstri ...

  7. poj 1741 Tree(树的点分治)

    poj 1741 Tree(树的点分治) 给出一个n个结点的树和一个整数k,问有多少个距离不超过k的点对. 首先对于一个树中的点对,要么经过根结点,要么不经过.所以我们可以把经过根节点的符合点对统计出 ...

  8. POJ 3723 Tree(树链剖分)

    POJ 3237 Tree 题目链接 就多一个取负操作,所以线段树结点就把最大和最小值存下来,每次取负的时候,最大和最小值取负后.交换就可以 代码: #include <cstdio> # ...

  9. POJ 1741.Tree and 洛谷 P4178 Tree-树分治(点分治,容斥版) +二分 模板题-区间点对最短距离<=K的点对数量

    POJ 1741. Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 34141   Accepted: 11420 ...

随机推荐

  1. iOS Automated Tests with UIAutomation

    参照:http://blog.manbolo.com/2012/04/08/ios-automated-tests-with-uiautomation#1 UI Automation JavaScri ...

  2. [LR]遇到的坑及常用技巧

    解决问题是需要智慧的 1.LR内部问题可以查看帮助文档 一般位于LR安装目录的bin目录下,如下图 打开Troubleshooting.chm文件,比如我们跑场景的过程中报错,报错信息为:-27995 ...

  3. [论文理解] Rapid-Object-Detection-using-a-Boosted-cascade-of-simple-features

    Rapid-Object-Detection-using-a-Boosted-cascade-of-simple-features 简介 文章是2001年发表的,是一篇很经典的Object Detec ...

  4. 解除phpMyAdmin导入大型MySQL数据库文件大小限制

    phpMyAdmin 导入大型数据库文件大小限制配置… 1. 修改 php.ini 文件中下列3项的值: upload_max_filesize, memory_limit 和 post_max_si ...

  5. centos Chrony设置服务器集群同步时间

    Chrony是一个开源的自由软件,像CentOS 7或基于RHEL 7操作系统,已经是默认服务,默认配置文件在 /etc/chrony.conf 它能保持系统时间与时间服务器(NTP)同步,让时间始终 ...

  6. Dojo中的选择器

    dom.byId(以前的dojo.byId):等同于js中的document.getElementById. http://www.cnblogs.com/tiandi/archive/2013/11 ...

  7. 01_4_Struts路径问题

    01_4_Struts路径问题 1. Struts路径问题说明 struts2中的路径问题是根据action的路径而不是jsp路径来确定,所有尽量不要使用相对路径. 虽然可以使用redirect方式解 ...

  8. 新环境安装 python3

    参考 安装 python3 时,不要覆盖原环境的 python2.因为环境中有些程序是依赖 2 的,比如 yum.直接覆盖是会影响环境的. 最好的是编译安装 python3,执行指令是用 python ...

  9. 为什么要在函数内部声明 var that = this 呢

    看一个例子 $('#conten').click(function(){ //this是被点击的#conten var that =this; $('.conten').each(function() ...

  10. w3resource_MySQL练习:Joins

    w3resource_MySQL练习题:Joins 1. Write a query to find the addresses (location_id, street_address, city, ...