数据结构 uva 112-Tree Summing

 

题目链接:

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=48

 

题目意思:

用括号方式给你一颗二叉树,一个预期的值result,如果从根到叶子节点所有的节点的值的和能够等于result,则输出yes,否则输出no.

 

解题思路:

由于题目给的是有任意空格和回车,所以先把括号和数字全部存入到字符数组中,跳过空格和回车,然后再处理,借助栈的结构建一颗树,然后用dfs求解从根到叶子节点的sum值。

本题的关键是处理空树的情况,例如  0 () 为no   ;   5 (5()(1()()))  为 no ;

 

代码:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<queue>
#define eps 1e-6
#define INF (1<<20)
#define PI acos(-1.0)
using namespace std;


struct NODE
{
    int value;
    int haveleft;
    int left,right;
}tree[5500];

char save[5200];
int result,flag;

void DFS(int node,int sum)
{
    if(flag==1)
        return ;
    sum+=tree[node].value;

    if(tree[node].left==0)  //到达了叶子节点
    {
        if(sum==result)
            flag=1;
        return ;
    }
    DFS(tree[node].left,sum);
    if(flag==1)
        return ;
    if(tree[node].right)
        DFS(tree[node].right,sum);    //注意 5 (5()(1()()))  这种情况为假 ,wa了好几次
    return ;

}

int main()
{

    while(scanf("%d",&result)!=EOF)
    {
        memset(tree,0,5500*sizeof(struct NODE));

        int cnt=0,tempcnt=0;
        char c;

        while((c=getchar())!='(')   //清除空格和回车
              ;
        save[cnt++]=c;  //读入第一个可用字符
        tempcnt++;
        while(tempcnt)  //括号匹配时结束
        {
            while((c=getchar())==' '||c=='\n')  //去掉中间的空格和回车
                ;
            if(c=='(')   //注意括号处理机制
                tempcnt++;
            else if(c==')')
                tempcnt--;
            save[cnt++]=c;
        }
        save[cnt++]='\0';
        if(save[0]=='('&&save[1]==')')  //如果是空树,无论结果怎样都输出no,wa了好几次
        {
            printf("no\n");
            continue;
        }

        stack<int>mystack;  //记住二叉树的标号

        int cur,num=0;
        sscanf(&save[1],"%d",&cur);  //去掉前括号后读入一个整数

        num++;   //二叉树的标号
        mystack.push(num);
        tree[num].value=cur;  //树中的值

        int len=1;


        while(!mystack.empty())
        {
            for(;;len++)      //跳过整数占用的字符
                if(save[len]=='('||save[len]==')')
                    break;

            if(save[len]=='('&&save[len+1]!=')')  //读入一个整数
            {
                sscanf(&save[++len],"%d",&cur);

                ++num;
                mystack.push(num);    //把该树的标号放入栈中
                tree[num].value=cur;
            }
            else if(save[len]==')'&&save[len-1]!='(')  //出栈处理,建二叉树
            {
                int temp1,temp2;

                temp1=mystack.top();
                mystack.pop();
                if(!mystack.empty())  //注意根的处理,要判断一下
                {
                    temp2=mystack.top();
                    if(tree[temp2].haveleft==0)  //如果左树已经没处理,处理左树
                    {
                        tree[temp2].left=temp1;
                        tree[temp2].haveleft=1;
                    }
                    else                 //如果左树已经处理,则处理右树
                        tree[temp2].right=temp1;

                }

            }
            len++;

        }
        flag=0;
        DFS(1,0);  //dfs计算结果
        if(flag==1)
            printf("yes\n");
        else
            printf("no\n");

    }


    return 0;
}





 

 

你可能感兴趣的:(数据结构 uva 112-Tree Summing)