UVa 112:Tree Summing 二叉树构造, 二叉树路径和

题目链接:

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=&problem=48&mosmsg=Submission+received+with+ID+10280379

题目类型: 数据结构, 二叉树

加强版样例输入:

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 ()
0 ()
5 (5 () ())
5 ( 5 () () )
5 (1 (3 () ()) (4 () ()))
5 (18 ( - 13 ( ) ( ))())
0 (1 ()(-2 () (1()()) ) )
2 (1 () (1 () (1 () () ) ) )
10 (5 () (5 () (5 () (5 () (4 () () ) ) ) ) )
10 (5 () (5 () (5 () (5 ( 3 () () ) (4 () () ) ) ) ) )
20 (5 () (5 () (5 () (5 () (4 () () ) ) ) ) )

加强版样例输出:

yes
no
yes
no
no
yes
yes
yes
yes
yes
no
no
no
no

题目大意:

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

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

也是空的。

解题思路:

这题比较难搞的是输入, 有括号,有数字,又有空格, 而且还会有陷阱,比如负号和数字之间可能也会有空格。于是专门写了个input()函数负责输入,用

本文URL地址:http://www.bianceng.cn/Programming/sjjg/201410/45533.htm

getchar()一个一个读, 过滤掉空格,保存到一个数组里。然后再处理。  

二叉树建好之后, 进行深搜,得到路径和。

对于空括号, 用一个简单的处理,即把那个结点数据赋值为一个负无穷,而不是空指针, 这样深搜时,如果有个结点数据值是负无穷的,则不处理。

#include<iostream>
#include<cstdio>
#include<cctype>
#include<cstring>  

const int END = -214748364;
using namespace std;  

class Node{
public:
    int data;
    Node *parent;
    Node *left;
    Node *right;
};  

bool found;
Node *root, *curRoot; // 根结点指针
Node node[10000]; // 先分配好内存
int nodeIndex;  

int sum;
char str[100000];  

// 创建一个只有根结点的二叉数,返回根结点指针
inline Node* CreateBTree(){
    nodeIndex = 1;
    node[0].parent = NULL;
    node[0].left   = NULL;
    node[0].right  = NULL;
    return &node[0];
}  

inline Node* NewNode(Node* parent){
    if(nodeIndex>10000-2){
        Node *t = new Node;
        t->left = NULL;
        t->right = NULL;
        t->parent = parent;
        return t;
    }
    node[nodeIndex].parent = parent;
    node[nodeIndex].left = node[nodeIndex].right = NULL;
    return &node[nodeIndex++];
}  

void Solve(){
    int i, j, ans=0;
    Node *temp;
    curRoot = NULL;
    bool flag = false;
    i=0;
    while(i<strlen(str)){
        // 进入结点并处理数据
        if(str[i]=='('){
            if(curRoot == NULL){
                root = curRoot = CreateBTree();
            }
            else{
                if(curRoot->left == NULL ){
                    curRoot->left = NewNode(curRoot); //给左儿子开辟空间
                    curRoot = curRoot->left;  // 进入左儿子
                }
                else{
                    curRoot->right = NewNode(curRoot); // 先给儿子指明父亲
                    curRoot = curRoot->right; // 进入右儿子
                }
            }
            // 直接碰到了右括号,说明没有数字,这个结点是终端标志
            ++i;
            if(str[i]==')'){
                curRoot->data = END;
                Node *parent = curRoot->parent;
                --i;
            } // 如果是数字
            else{
                int val;
                sscanf(&str[i], "%d", &val);
                curRoot->data = val;
            }
        }
        else if(str[i] == ')'){
            curRoot = curRoot->parent;
        }
        ++i;
    }
}
bool Input(){
    char ch;
    int cnt1=0, cnt2=0, index=0;
    while(ch = getchar()){
        if(ch=='(') ++cnt1;
        if(ch==')') ++cnt2;
        if(ch=='(' || ch==')' || ch=='-' || isdigit(ch))
            str[index++] = ch;
        if(cnt1 && cnt1==cnt2) break;
    }
    getchar();
    str[index] = '\0';
    if(cnt1==1 && cnt2==1) return false; // 如果只有一对括号,那么可以直接判断
    return true;
}  

void dfs(Node *root, int n){
    if(found) return ;
    if(root->left->data==END && root->right->data==END ){
        if(n+root->data == sum) found = true;
        return ;
    }
    if(root->left && root->left->data!=END) dfs(root->left, n+root->data);
    if(root->right && root->right->data!=END) dfs(root->right, n+root->data);
}  

int main(){
    freopen("input.txt", "r", stdin);
    while(~scanf("%d", &sum)){
        if(!Input()){
            printf("no\n");
        }
        else{
            Solve();
            found = false;
            dfs(root, 0);
            if(found) printf("yes\n");
            else printf("no\n");
        }
    }
    return 0;
}

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索no mapping found
, node
, 结点
, root
, 二叉树建立
, 二叉树 php
, 括号
, right
parent
构造平衡二叉树、构造二叉树、平衡二叉树的构造、二叉树的构造、构造最优二叉树,以便于您获取更多的相关知识。

时间: 2025-01-20 17:51:15

UVa 112:Tree Summing 二叉树构造, 二叉树路径和的相关文章

UVa 112 Tree Summing (scanf()去空格&amp;amp;递归&amp;amp;二叉树遍历)

112 - Tree Summing Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=48 Background LISP was one of the earliest high-level programming languages and, with FORTRAN, is one o

uva 112 Tree Summing

点击打开链接 题目意思:给定一个字符串,把字符串里面的数字建成一颗树,数字有可能是负号,所以这一题其实有很多可以学的,比如怎样输入会有多行,还有怎么建立一颗树,等等. 解题思路:我们用一个字符数组来存储读入的字符串,用一个栈来存储括号,判断如果栈为空并且读到换行那么就退出.我们可以先把根节点建好,建根节点调用creatnode()函数,注意数字可能是1234    -1234这些情况,所以判断.然后我们在从根节点后面的位置开始变量字符数组,如果是('(')则判断下一额是数字还是右括号,如果是数字

数组构造二叉树并打印的编程算法

数组: 构造二叉树, 需要使用两个队列(queue), 保存子节点和父节点, 并进行交换; 打印二叉树, 需要使用两个队列(queue), 依次打印父节点和子节点, 并进行交换; 二叉树的数据结构: struct BinaryTreeNode { int m_nValue; BinaryTreeNode* m_pParent; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; }; 代码: /* * main.cpp * * Created o

[LeetCode] Binary Tree Level Order Traversal 二叉树层次遍历(DFS | BFS)

目录:1.Binary Tree Level Order Traversal - 二叉树层次遍历 BFS 2.Binary Tree Level Order Traversal II - 二叉树层次遍历从低往高输出 BFS 3.Maximum Depth of Binary Tree - 求二叉树的深度 DFS4.Balanced Binary Tree - 判断平衡二叉树 DFS5.Path Sum - 二叉树路径求和判断DFS 题目概述:Given a binary tree, return

PHP构造二叉树算法示例

树(Tree)在数据结构还是很重要的,这里表示二叉树用括号表示法表示.先写一个二叉树节点类: // 二叉树节点 class BTNode { public $data; public $lchild = NULL; public $rchild = NULL; public function __construct($data) { $this->data = $data; } } 然后构造二叉树: function CreateBTNode(&$root,string $str) { $s

C#语言怎么利用文本框构造二叉树?二叉树的构造也是靠递归么?

问题描述 C#语言怎么利用文本框构造二叉树?二叉树的构造也是靠递归么? C#语言怎么利用文本框构造二叉树?二叉树的构造也是靠递归么? 解决方案 http://www.cnblogs.com/yjmyzz/archive/2010/12/01/1892403.html 解决方案二: 利用广义表非递归构造二叉树二叉树的构造构造二叉树

关于二叉树中根和后根构造二叉树求大神帮忙看看有没有什么问题?

问题描述 关于二叉树中根和后根构造二叉树求大神帮忙看看有没有什么问题? #include using namespace std; template class BinaryNode { public: T data; BinaryNode *left, *right; BinaryNode(T data, BinaryNode*left = NULL, BinaryNode*right = NULL) { this->data = data; this->left = left; this-

PHP实现二叉树/线索二叉树

PHP实现二叉树.线索二叉树,如下代码: <?php      require 'biTree.php';        $str = 'ko#be8#tr####acy#####';           $tree = new BiTree($str);      $tree->createThreadTree();        echo $tree->threadList() . "\n";从第一个结点开始遍历线索二叉树      echo $tree->

森林转换成二叉树以及二叉树还原为森林代码

/* 森林转换成二叉树 思路:u的孩子节点为v1, v2, v3....(v1,v2,....互为兄弟节点) 那么将u的一个孩子节点(v1)连在u的左子树上,那么其他的孩子节点都连在v1的右子树上! */ #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; int g[15][15]; int par[15];//如果该节