uva 112 Tree Summing

点击打开链接

题目意思:给定一个字符串,把字符串里面的数字建成一颗树,数字有可能是负号,所以这一题其实有很多可以学的,比如怎样输入会有多行,还有怎么建立一颗树,等等。

解题思路:我们用一个字符数组来存储读入的字符串,用一个栈来存储括号,判断如果栈为空并且读到换行那么就退出。我们可以先把根节点建好,建根节点调用creatnode()函数,注意数字可能是1234    -1234这些情况,所以判断.然后我们在从根节点后面的位置开始变量字符数组,如果是(‘(’)则判断下一额是数字还是右括号,如果是数字则continue,如果是右括号则,执行creatnode()函数产生新的节点。中间数字有可能是多位的情况,所以要做好处理,即传入creatnode()的参数要做好。树建好以后就是搜素路径和是否为sum,我们用深搜来处理,(中间可以用前序遍历来判断是否建好了树),我们知道对于叶子节点,那么它的两个子树的al都是Min,所以在搜索时候处理做好即可。

代码:

#include <cmath>
#include <cstdio>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <stack>
#include <list>
#include <algorithm>
using namespace std;

const int Min = -999999999;//定义一个宏为无穷小,后面遇到左括号后面没有数字时要处理
char ch , c[50000];//字符数组存储字符串
int sum, tempsum, mark, cmark, Found , len;
stack<char>st;//栈存储括号
//二叉树的结构体
struct node {
    int val;
    struct node *lchild, *rchild, *father;//用一个father指针来指向当前指针cur的父亲节点
};
node *root, *temp, *cur;

//初始化函数用来对每一个node 指针初始化
void init(node *u , int m) {
    u -> father = NULL;
    u -> lchild = NULL;
    u -> rchild = NULL;
    u -> val = m;
}
//建立新的节点
void createnode(int n) {
    temp = new node;
    init(temp , n);//初始化temp,临时的指针
    if (cur->lchild == NULL) {//如果左子树为空,把temp赋给左子树
        cur -> lchild = temp;
        temp = cur;//temp存储此时的cur
        cur = temp -> lchild;//当前指针指向左子树
    }
    else {//如果右子树为空,把temp赋给右子树
        cur -> rchild = temp;
        temp = cur;
        cur = temp -> rchild;
    }
    cur -> father = temp;//cur的父亲节点为temp
}
//创建根节点函数(最开始用到)
int creatroot() {
    int i = 1 , j ,  k ,tempnum = 0, cmark = 1;
    if (c[1] == '-') { //如果有负号要处理
        cmark = -1 , i = 2 ;
    }
    j = i;
    while(isdigit(c[j]))
        j++;
    j--;
    for(k = 0 ; j >= i ; j-- , k++)
        tempnum += (pow(10 , k)) * (c[j] - '0');
    init(root , cmark * tempnum);//建立根节点
    cur = root;//当前节点赋给根节点
    i += k;
    return i;
}
//输入函数
void input(){
    int i = 0;
    while(ch = getchar()){
        if(ch == ' ' || ch == '\n')//判断跳过函数
            continue;
        else{
            c[i] = ch;
            if(c[i] == '(') st.push(c[i]);
            if(c[i] == ')') st.pop();
            if(st.empty())  return;//栈为空则退出
            i++; len = i;
        }
    }
}
//处理函数
void solve(int i) {
    int mark = 1;//mark用来标记是正数还是负数
    while (i <= len){
        if (c[i] == '-') {//遇到符号则把mark标记为-1
            mark = -1;
            i++;
            continue;
        }
        if (c[i] == ')') {//遇到右括号则cur指向它的父亲节点
            cur = cur -> father;
            i++;
            mark = 1;
            continue;
        }
        if (isdigit(c[i])) {//如果是数字进行产生
            int tempnum = 0 , j , k;
            j = i + 1;
            while(isdigit(c[j])){
                j++;
            }
            j--;
            for(k = 0 ; j >= i ; j-- , k++){
                tempnum += (pow(10 , k)) * (c[j] - '0');//里面有多个数字情况
            }
            createnode(mark * tempnum);
            i += k;
            mark = 1;
            continue;
        }
        if (c[i] == '(') {
            if(c[i+1] == ')')
                createnode(-999999999);
            i++;
            mark = 1;
            continue;
        }
    }
}
//dfs搜索函数路径值函数
void judge(int tempsum, node *cur) {
    temsum += cur->val;
    if (Found)
        return;
    if (tempsum == sum && cur->lchild->val == Min && cur->rchild->val == Min) {//说明找到了该路径
        Found = 1;
    }
    if (cur -> lchild != NULL && cur -> lchild -> val != Min)
        judge(tempsum  , cur -> lchild);//继续向左儿子搜素
    if (cur -> rchild != NULL && cur -> rchild -> val != Min)
        judge(tempsum  , cur -> rchild);//继续像右儿子搜素
}
//栈清空
void clear() {
    while (!st.empty())
        st.pop();
}
//主函数
int main(){
    int i;
    while (~scanf("%d", &sum)) {
        root = new node;
        Found = 0;
        input();
        if(len == 1) { //如果是这种 5 () 这种情况直接输出
            printf("no\n") ; continue;
        }
        if(len != 1) {
            i = creatroot() , solve(i);//调用函数
        }
        judge(0 , root);//搜索
        if (Found)       printf("yes\n");
        if (Found == 0)  printf("no\n");
        clear();//栈清空
    }
    return 0;
}
时间: 2024-08-03 19:11:10

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 二叉树构造, 二叉树路径和

题目链接: 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()())))

UVa 152 Tree&#039;s a Crowd (暴力)

152 - Tree's a Crowd Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=98&page=show_problem&problem=88 Dr William Larch, noted plant psychologist and inventor of the phrase ``Think like

UVa 548 Tree:中序遍历&amp;amp;后序遍历&amp;amp;DFS

548 - Tree Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=104&page=show_problem&problem=489 You are to determine the value of the leaf node in a given binary tree that is the termina

uva 548 Tree

点击打开链接uva 548 思路: 二叉树 分析: 1 题目给定一棵二叉树的中序序列和后序序列求这个二叉树里面,根节点到叶子节点的最短路径的叶子节点的值,如果有多条路径输出最小的叶子节点 2 题目说最多有10000个节点,但是由于题目所说的二叉树并不是完全二叉树,所以这里建立二叉树并不能够利用静态的思想,应该要利用动态的增加 3 建立了二叉树之后,只要按照前序遍历的思路即可求出ans 代码: #include<cstdio> #include<cstring> #include&l

uva 536 - Tree Recovery

点击打开链接uva 536 思路: 二叉树 分析: 1 题目给定前序序列和中序序列,要求二叉树的后序序列 2 建好二叉树之和直接遍历输出即可,裸题 代码: #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int MAXN = 30; char preOrder[MAXN]; char midOrder[MA

UVa 11332 Summing Digits (water ver.)

11332 - Summing Digits Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=2307 For a positive integer n, let f(n) denote the sum of the digits of n when repr

UVa 10247 Complete Tree Labeling:组合数学&amp;amp;高精度

10247 - Complete Tree Labeling Time limit: 15.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=1188 A complete k-ary tree is a k-ary tree in which all leaves have same d

UVa 548:Tree 二叉树的重建——中序遍历与后续遍历进行建树

题目链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=104&page=show_problem&problem=489 题目类型: 数据结构, 二叉树 题目大意: 给两个组数字,都是在同一棵二叉树上的,第一组是按中序遍历(inorder)顺序输出的,第二组是按后序遍历(postorder)输出的, 根据这两组数据构建出原来的二叉树,然后计算从根结点到每个叶子结