这题应该可以用栈结构直接求解的,效率也更高,但是因为是第一次写tree,还是直接模拟了,tree写的其实挺顺利,但是老WA,最后才发现是负数处理有问题,因为输入很坑,处理的时候把负号可能出现给忘了。。。。。。
菜鸟代码不好看:。。
#include<iostream>
#include<string>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cmath>
#include<set>
#include<ctime>
#include<cctype>
#include<memory>
#include<cstdlib>
#include<map>
#include<queue>
#include<stack>
#include<climits>
#include<list>
using namespace std;
int cont=-1;
struct node/节点
{
node* left;
node* right;
node* father;
int value;
bool le;
};
node* newnode(node* f)///新建节点
{
node* n=new(node);
n->left=n->right=NULL;
n->father=f;
n->le=false;
return n;
}
void rmvtree(node* a)///清除树
{
if(NULL==a)
return;
rmvtree(a->left);
rmvtree(a->right);
delete a;
}
int nums[10000];
void get(node* n)///获取所有叶子的值
{
if(n->right!=NULL)
get(n->right);
if(n->left!=NULL)
get(n->left);
if(n->right==NULL&&n->left==NULL)
nums[++cont]=n->value;
}
int main()
{
int x,temp;
char c;
node* now;
while(cin>>x)
{
cont=-1;
while(cin>>c)
{
if(!isspace(c))
break;
}
while(cin>>c)
{
if(!isspace(c))
break;
}//以上是处理空格
if(')'==c)
{
cout<<"no"<<endl;
continue;
}是空树直接返回
cin.putback(c);
cin>>temp;
node* root;
root=now=newnode(NULL);
now->value=temp;初始化根
while(true)
{
while(cin>>c)
{
if(!isspace(c))
break;
}又是空格
if('('==c)
while(cin>>c)
{
if(!isspace(c))
break;
}
if(isdigit(c)||'-'==c)/好久才想到在这出问题的。。。。
{
cin.putback(c);
cin>>temp;
if(!now->le&&NULL==now->left)///左子树未初始化且为空时初始化左子树
{
now->left=newnode(now);
now=now->left;
now->value=now->father->value+temp;
}
else
{
now->right=newnode(now);
now=now->right;
now->value=now->father->value+temp;
}
}
else
{
if(!now->le&&NULL==now->left)/左子树为空标记
{
now->le=true;
}
while(cin>>c)
{
if(isspace(c))
continue;
if(')'==c)
{
if(now->father!=NULL)
now=now->father;
else
goto here;
}
if('('==c)
break;
}
}
}
here:
get(root);
bool fund=false;
for(int i=0;i<=cont;i++)/处理数据
{
if(x==nums[i])
{
fund=true;
break;
}
}
if(fund)
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
rmvtree(root);
}
return 0;
}
写了个栈结构的,括号处理还是问题。。。结果发现效率居然比前面那个还低一点,应该是用cin.putback用的太多了,看了别人的代码,其实应该把前括号考虑进去做括号配对会更好的
int leave[10000];
int mark[10000];
///mark数组用于标记当前节点已经遇到的")"的数量
///经过观察发现,每个节点在该节点的层次上遭遇3个“)”后弹出,所以用这个数组记录数量
int main()
{
int x,temp;
char c;
int now;
while(cin>>x)
{
int marknow=0;
memset(mark,0,sizeof(mark));
bool isleaf=true;///用于判断当前节点是否为叶子
stack<int> tree;
int cont=-1;
while(cin>>c&&isspace(c));
while(cin>>c&&isspace(c));
if(')'==c)
{
cout<<"no"<<endl;
continue;
}
cin.putback(c);
cin>>temp;
tree.push(temp);
while(true)
{
while(cin>>c&&isspace(c));
///对于空格的处理和前面一样
///也可以将空格全部去掉把数据保存在string里直接使用,树的处理可以直接对字符串递归处理,但是这个我不想再试了。。。。。。。
if(')'==c&&2==mark[marknow]&&isleaf)
{
leave[++cont]=tree.top();
tree.pop();
isleaf=false;///如果子节点pop那么回溯到的上一个节点,其父节点一定不是叶子
mark[--marknow]++;
}
else if(')'==c&&2!=mark[marknow])
{
mark[marknow]++;
}
else if(')'==c&&!isleaf&&2==mark[marknow])
{
mark[--marknow]++;
tree.pop();
}
else if(isdigit(c)||'-'==c)
{
isleaf=true;
mark[++marknow]=0;
cin.putback(c);
cin>>temp;
now=temp+tree.top();
tree.push(now);
}
if(tree.empty())
break;
}
bool fund=false;
for(int i=0; i<=cont; i++)
if(x==leave[i])
{
fund=true;
break;
}
if(fund)
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
}
return 0;
}