2655: [UVA112]樹求和
時間限制: 1 Sec 內存限制: 128 MB提交: 33 解決: 17
[提交][狀態][我的提交]
題目描述
給定一棵二叉樹,結點的值均爲整數。問樹上是否存在一條從根到葉的路徑,使得路徑上各結點之和爲給定的整數。如圖所示,二叉樹共有4條從根到葉的路徑。它們的和分別爲27, 22, 26, 18。
在本題中,輸入二叉樹用括號表示法。上圖的二叉樹可表示爲:(5 (4 (11 (7 () ()) (2 () ()) ) ()) (8 (13 () ()) (4 () (1 () ()) ) ) ),樹上的葉結點表示爲:(integer () () )
顯然,一棵空樹是沒有路徑的,所以對空樹的詢問,答案一定是"no"。
輸入
多組數據,每組數據的格式爲:
第1行:先是1個整數,表示指定的某個值,再是1個空格,再是1個字符串,以括號表達式的方式表示的一棵二叉樹. 保證輸入的二叉樹是合法的。在括號表達式描述中,無空格。一棵樹最多有256個節點,所有結點的值均不超過1000
輸出
對每一行表示的二叉樹,若存在從根到葉的路徑和等於指定的整數,則輸出"yes",否則輸出"no"
樣例輸入
(如果複製到控制檯無換行,可以先粘貼到文本編輯器,再複製)
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 ()
樣例輸出
yes
no
yes
no
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
using namespace std;
int n,len;
char s[100010];
bool vis[2560010];
int find_pair(int x){
int flag=0;
for(int i=x;i<=len;i++){
if(s[i]=='(') flag++;
else if(s[i]==')') flag--;
if(!flag) return i;
}
return -1;
}
int find_num(int l,int r,int &v){
sscanf(s+l,"%d",&v);
for(int i=l;i<=r;i++)
if(s[i]<'0'||s[i]>'9')
return i;
return -1;
}
void build(int l,int r,int now){
if(l>r) return ;
if(l+1==r){
vis[now]=1;return ;
}
if(s[l]=='('&&s[r]==')'){
build(l+1,r-1,now);return ;
}
int v;
int pos1=find_num(l,r,v);
int pos2=find_pair(pos1);
if(s[pos1]=='('&&s[pos1+1]==')'&&s[pos1+2]=='('&&s[pos1+3]==')'){
vis[now+v]=1;return ;
}
build(pos1,pos2,now+v);
build(pos2+1,r,now+v);
}
int main(){
while(~scanf("%d%s",&n,s+1)){
memset(vis,0,sizeof(vis));
build(1,len=strlen(s+1),0);
printf("%s\n",vis[n]?"yes":"no");
}
return 0;
}