1、这道题对我来说有很大难度,但我是完全靠自己做的,晚上6点开始,凌晨3点才做出来,花了这么长时间,而且是一次AC了这道通过率仅为20%的题目,其中的成就感简直无法用语言形容。
2、这道题考察树的建立以及宽度优先搜索。首先,题目给出的字符串是不规则的,要先整理成我们常见的形式才可以,具体用getchar,见代码。
3、其次,树的建立利用了栈,本题的难点是栈不可能既保存字符型的括号和结点型的结点,所以必须要两个栈。我想了一个办法,就是第一个栈用来保存“索引”,括号的话,就用整型的负极大值代替(防止和结点的取值搞混,因为没有结点会取这个值),至于结点,则再开辟一个栈,然后在原先的栈内本应保存结点的位置保存“结点在第二个栈中的下标”,即“索引”,是不是很像括号匹配问题?这个方案实现起来不是非常容易,具体见代码。
4、宽度优先搜索没什么说的,注意sum数组的清零,以及判断“judge是否变为true”的语句需要写两遍。
5、最后注意释放内存空间。
6、网上有神犇写了非常简洁的代码,甚至不用建树,但我认为还是按照常规思路来想较好,原因有二:第一,神犇的方法一般人想不到,尤其是比赛的时候;第二,本题考查的就是建树和bfs,应该借着这道题将知识好好温习一遍。
#include <cstdio>#include <cstring>
#include <cctype>
#include <cstdlib>
#define Max 2147483647
using namespace std;
typedef struct Tnode
{
int v;
struct Tnode *left,*right;
bool left_saw;
}Node;
bool flag,judge;
char ch;
char s[10000];
int stack[10000],ans,p,top,topc;
Node* chart[10000];
Node* root;
void init(void)
{
int count1=0,count2=0;
while(ch=getchar())
{
if(ch=='(')
{
count1++;
flag=true;
s[p++]='(';
}
if(ch=='-'||isdigit(ch))
{
s[p++]=ch;
}
if(ch==')')
{
count2++;
s[p++]=')';
}
if(count1==count2&&flag)
break;
}
return;
}
Node* newnode(void)
{
Node*u=(Node*)malloc(sizeof(Node));
if(u!=NULL)
{
u->left=u->right=NULL;
u->left_saw=false;
}
return u;
}
void addnode(void)
{
int i=0,num;
Node*u=newnode();
chart[0]=u;
while(s[i])
{
if(s[i]=='(')
{
top++;
stack[top]=-Max;
}
if(s[i]=='-'||isdigit(s[i]))
{
sscanf(&s[i],"%d",&num);
u=newnode();
u->v=num;
topc++;top++;
chart[topc]=u;stack[top]=topc;
while(s[i]!='(') i++;
i--;
}
if(s[i]==')')
{
if(stack[top]==-Max)
{
if(chart[topc]->left_saw==false)
chart[topc]->left=NULL;
else
chart[topc]->right=NULL;
top--;
}
else
{
if(stack[top]>0)
{
if(chart[stack[top]-1]->left_saw==false)
{
chart[stack[top]-1]->left=chart[stack[top]];
chart[stack[top]-1]->left_saw=true;
}
else
chart[stack[top]-1]->right=chart[stack[top]];
top-=2;topc--;
}
}
}
i++;
}
root=chart[topc];
return;
}
int bfs(void)
{
int front=0,rear=1;
judge=false;
Node*q[10000];
int sum[10000];
memset(sum,0,sizeof(sum));
q[0]=root;sum[0]=root->v;
while(front<rear)
{
Node*u=q[front++];
if(u->left!=NULL)
{
q[rear++]=u->left;
sum[rear-1]=sum[front-1]+q[rear-1]->v;
}
if(sum[rear-1]==ans&&q[rear-1]->left==NULL&&q[rear-1]->right==NULL)
{
judge=true;
break;
}
if(u->right!=NULL)
{
q[rear++]=u->right;
sum[rear-1]=sum[front-1]+q[rear-1]->v;
}
if(sum[rear-1]==ans&&q[rear-1]->left==NULL&&q[rear-1]->right==NULL)
{
judge=true;
break;
}
}
if(!judge)
printf("no\n");
else
printf("yes\n");
return 0;
}
void remove_tree(Node*u)
{
if(u->left==NULL&&u->right==NULL) {free(u);return;}
if(u->left!=NULL)
remove_tree(u->left);
if(u->right!=NULL)
remove_tree(u->right);
}
int main(void)
{
while(scanf("%d",&ans)==1)
{
flag=false;p=0;top=topc=-1;
memset(s,'\0',sizeof(s));
memset(stack,0,sizeof(stack));
memset(chart,NULL,sizeof(chart));
init();
if(s[0]=='('&&s[1]==')'&&s[2]=='\0')
{
printf("no\n");
continue;
}
addnode();
bfs();
remove_tree(root);
}
return 0;
}