[UVA112]樹求和(BZOJ2655)

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
分析:其實這道題白癡到極點(23333333然而噁心的括號輸入我寫了半天qnq),一邊建樹(其實不用,模擬建樹dfs就可以了233333333),到葉子節點時記錄可達到的數23333 qwq
#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;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章