uva 10562

这是一个很有意思的题目,一看就知道是递归的一个过程,但是要注意的是这句话:

The labels of each of node can be any printable character except for the symbols '-', '|', ' ' (space) and '#'.

所以不一定只有字母才是结点,晕......

#include <iostream> #include <cstring> using namespace std ; const int maxn = 200 + 10 ; char str[maxn][maxn] ; char node[maxn] ;//用于存储结点 int rcount ;//保存二维数组的行数 int ncount ;//保存结点个数 //初始化 void init() { rcount = 0 ; ncount = 0 ; memset( str , 0 , sizeof( str ) ) ; memset( node , 0 , sizeof( node ) ) ; return ; } //判断是不是结点字符( 注意题目中说所有可打印的字符都可以是结点字符,除了空格,‘|’ ,‘#’ 和‘-’,就是这个让我wa,唉,还是要多看题呀) bool islable( char c ) { if( c == ' ' || c == '|' || c == '#' || c == '-' || c == '/n' ) return false ; return true ; } //深度优先遍历树 void dfs( char s[][maxn] , int b , int e , int r ) { node[ncount++] = '(' ;//每次都以前括号开始 for( int i = b ; i <= e && i < strlen( s[r] ) ; i++ ) if( islable( s[r][i] ) ) { if( s[r+1][i] == '|' )//如果有子结点 { node[ncount++] = s[r][i] ;//保存父结点 int nb = -1 ; int ne = strlen( s[r+2] ) - 1 ; for( int j = i ; j >= 0 ; j-- ) if( s[r+2][j] != '-' ) { nb = j ; break ; }//找到子树的左端 for( int j = i ; j < strlen( s[r+2] ) ; j++ ) if( s[r+2][j] != '-' ) { ne = j ; break ; }//找到子树的右端 if( nb == -1 ) nb = 0 ; dfs( s , nb , ne , r + 3 ) ;//递归遍历 } else if( islable( s[r][i] ) )//如果没有子结点,它后面是一对括号 { node[ncount++] = str[r][i] ; node[ncount++] = '(' ; node[ncount++] = ')' ; } } node[ncount++] = ')' ;//每次都以后括号结束 return ; } int main() { int ncase ; cin >> ncase ; getchar() ; while( ncase-- ) { init() ; while( 1 ) { gets( str[rcount] ) ; if( str[rcount++][0] == '#' ) break ; } dfs( str , 0 , strlen( str[0] ) - 1 ,0 ) ; cout << node << endl ; } return 0 ; }

你可能感兴趣的:(uva 10562)