您的位置:首页 > 其它

poj 1145 (uva 112) Tree Summing

2015-12-31 02:41 501 查看
原题:

Tree Summing

Time Limit: 1000MS Memory Limit: 10000K

Total Submissions: 8166 Accepted: 1960

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

题目大意:

用括号的方式给你一颗树,让你找这棵树上从根节点到叶子节点上值的和是否等于开始所给的那个数。

[code]#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<stack>
#include<sstream>
using namespace std;
int n;
string s;
stack<string> S;
bool solve()
{
    string tem;
    stringstream ss;
    int num,tot=0;
    for(int i=0;i<s.size();)
    {
        tem.clear();
        ss.clear();
        num=0;
        if(s[i]=='(')
        {
            S.push("(");
            i++;
        }
        else
        {
            if(s[i]!=')')
            {
                while((s[i]>='0'&&s[i]<='9')||s[i]=='-')
                {
                    tem+=s[i];
                    i++;
                }
                S.push(tem);
                ss<<tem;
                ss>>num;
                tot+=num;
                if(s[i]=='('&&s[i+1]==')'&&s[i+2]=='('&&s[i+3]==')'&&tot==n)//叶子节点
                return true;
            }
            else//字符为')'时
            {
                tem=S.top();
                S.pop();
                if(tem!="(")//是数字
                {
                    ss<<tem;
                    ss>>num;
                    S.pop();//弹出'('
                    tot-=num;
                }
                i++;
            }
        }
    }
    return false;
}

int main()
{
    ios::sync_with_stdio(false);
    int l,r;
    char c;
    while(cin>>n)
    {
        l=r=0;
        while(true)
        {
            c=cin.get();
            if(c=='(')
                l++;
            if(c==')')
                r++;
            if(c=='('||c==')'||(c>='0'&&c<='9')||c=='-')
                s+=c;
            if(l==r&&l!=0)
            break;
        }
        if(l==1&&r==1&&s.size()>2)
        {
            cout<<"no"<<endl;
            continue;
        }
        if(solve())
        cout<<"yes"<<endl;
        else
        cout<<"no"<<endl;
    }
    return 0;
}


思路:

思路很简单,可以用栈实现,也可以用递归的方式来实现。本人较笨较懒,就用土办法。

首先判断如果是一个数字而且后面跟着()()那就一定是一个根节点,如果是一个左括号那就压入栈中。如果是一个右括号的话就要和你栈中存储的东西相比对,如果你当前栈顶是一个数字,那就要把这个数字弹出来代表回溯的过程,同时也要把你计算树的路径的和前去当前的值,如果当前栈顶是一个左括号,那么就和右括号相抵消就行了。

注意这题有负数! 输入数据的时候要吸掉回车和空格。

还有,poj上过了,uva上没过~不过我还是厚颜无耻的把代码贴上来了,如果有错误一定要告诉我,十分感激!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: