Undraw the Trees (Uva 10562)

  题意:将多叉树转化为括号表示法。每个结点用除了‘-’, ‘|’, ‘ ’(空格), ‘#’ 的其他字符表示,每个非叶结点的正下方会有一个 ‘|’ 字符,然后下面是一排 ‘-’ 字符,恰好覆盖所有子节点的上方。单独的一行 ‘#’ 为数据结束。

  例样输入:

2
   A
   |
--------
B C   D
    |   |
 ----- -
 E  F G
#
e
|
----
f g
#

例样输出:

  (A(B()C(E()F())D(G())))
  (e(f()g()))

  

  思路:

  将输入数据存入二维数组,在二维数组中进行递归建树。

  对于一个结点(r, c),若 (r+1, c) 这个字符为 ‘|’,则说明存在子树,对其进行递归建树。

  确定子结点点的方式为:首先确定 (r+2, c) 这个位置的字符串 “----...” 的范围 left, right,再从(r+3, left), (r+3, right) 这个范围寻找子结点。

  核心代码:

  

void build(int r, int c){
    printf("%c", a[r][c]);
    if(a[r+1][c] == ‘|‘){    //如果该节点有子树
        int left=c, right=c;
        range(left, right, r+2);    //传引用,确定字符串 "----..." 的范围
        //递归子结点
        for(int i=left; i<=right; i++){
            if(a[r+3][i]!=‘ ‘ && a[r+3][i]!=‘\0‘ && a[r+3][i]!=‘#‘ && a[r+3][i]!=‘-‘ &&a[r+3][i]!=‘|‘){ //确定该字符是不是结点
                 build(r+3, i);
            }
        }
    }
    printf(")");
}

  结点后面的括号中,为子树。若为叶子结点,则括号中为空。

AC 代码:

/* Undraw the Trees (UVa 10562)*/
#include <iostream>
#include <cstring>
#include <string>
using namespace std;

const int MAX = 205;

char a[MAX][MAX];

void input();        //输入
void build(int r, int c);                //建立树
void range(int &left, int &right, int r);    //确定第 r 行 left(right) 位置 "----..." 字符串的范围。 

int main(){
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    int T;
    cin >> T;    getchar();    //过滤掉结尾的回车
    while(T--){
        input();
        printf("(");
        for(int i=0; i<MAX && a[0][i]!=‘\0‘; i++){
            if(a[0][i]!=‘ ‘)
                build(0, i);
        }
        printf(")\n");
        /*for(int i=0; i<7; i++){
            puts(a[i]);
        }
        printf("\n");*/
    }
    return 0;
}

void input(){
    int i;
    memset(a, 0, sizeof(a));
    for( i=0; ; i++){
        gets(a[i]);
        if(strcmp(a[i],"#") == 0)
            break;
    }
    a[i][0]=0;
} 

void build(int r, int c){
    printf("%c(", a[r][c]);
    if(a[r+1][c] == ‘|‘){    //如果该节点有子树,则递归建立子树
        int left=c, right=c;
        range(left, right, r+2);    //确定字符串 "----..." 的范围

        for(int i=left; i<=right; i++){
            if(a[r+3][i]!=‘ ‘ && a[r+3][i]!=‘\0‘ && a[r+3][i]!=‘#‘ && a[r+3][i]!=‘-‘ &&a[r+3][i]!=‘|‘){    //如果找到子节点,则递归子节点
                 build(r+3, i);
            }
        }
    }
    printf(")");
}

void range(int &left, int &right, int r){
    for(; left>=0 && a[r][left]==‘-‘; left--);  left++;
    for(; right<MAX && a[r][right]==‘-‘; right++);   right--;
}
时间: 2024-12-24 00:08:49

Undraw the Trees (Uva 10562)的相关文章

Undraw the Trees 字符串数组递归画树

Undraw the Trees 题目抽象:给出一个二维字符数组表示的树,将其表示成一维字符数组表示的树. 思路:直接在二维字符数组中递归画树即可. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 const int MS=205; 8

UVa 10562 Undraw the Trees 看图写树

转载请注明: 仰望高端玩家的小清新 http://www.cnblogs.com/luruiyuan/ 题目大意: 题目传送门:UVa 10562Undraw the Trees 给定字符拼成的树,将这些树转换成特定的括号表示的树 思路: 首先,观察样例,可以发现就是先序遍历的顺序,因此可以确定dfs 但是,还有几个地方需要考虑: 同一级的结点,在同一级的括号中 由于顺序满足先序遍历,因此不需要存储树,更不需要构建树,直接在遍历过程中输出即可. 空树:即输入为:# 时的树的处理,我不建议在此进行

uva 10562 undraw the trees(烂题) ——yhx

无需建树,递归即可. 为什么说是烂题呢? 1.pdf里的样例数据复制过来丢了空格,导致我调了很久都没有发现问题在哪. 2.如样例2所示,4个'-'下面却少一格. 3.空树,即只有'#'需要特殊处理. 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<string> 5 using namespace std; 6 char map[210][210]; 7 int m

UVa 10562 Undraw the Trees

题意: 将树的关系用字符串的形式给出 分析: 直接dfs搜索,第i行第j个如果是字母,判断i+1行j个是不是'|'是的话在第i+2行找第一个'-',找到后在第i+3行找字母,重复进行. 代码: #include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;const int maxn=210;int n;char a[maxn][ma

UVa 10562 (特殊的输入处理方式) Undraw the Trees

题意: 给出一个二维字符数组,它代表了一棵树.然后将这棵树转化为括号表示法(以递归的形式). 分析: 这道题最大的特色就是对数据的处理方式,里面用到了一个 fgets() 函数,这个函数的功能有点像c++里面的cin.getline() 函数介绍: 从文件结构体指针stream中读取数据,每次读取一行.读取的数据保存在buf指向的字符数组中,每次最多读取bufsize-1个字符(第bufsize个字符赋'\0'),如果文件中的该行,不足bufsize个字符,则读完该行就结束.如若该行(包括最后一

UVa 10562 看图写树

题目:题目就是给出一幅ASCII字符构成的树的图,然后转换成由字符括号构成的树的表示形式.可以知道,树有孩子结点的话,正下方会有一个字符 '|' ,紧接着会有一个覆盖所有孩子结点的字符序列"-------",然后其下就是孩子结点. 思路:先将所有数据读下来.然后递归处理,给定一个左右边界,在该边界内逐个检查字符,如果是结点字符,则判断有无孩子等后续处理. 注意:因为每行会有空格,所以不能用scanf输入,换成fgets的话会保留有换行符(当然,可以进行处理或后续判断),这里使用的是ge

UVA题目分类

题目 Volume 0. Getting Started 开始10055 - Hashmat the Brave Warrior 10071 - Back to High School Physics 10300 - Ecological Premium 458 - The Decoder 494 - Kindergarten Counting Game 414 - Machined Surfaces 490 - Rotating Sentences 445 - Marvelous Mazes

二叉树基础练习

前序遍历(先根遍历):根,左子树,右子树 中序遍历:左子树,根,右子树后序遍历:左子树,右子树,根 先序遍历:ABDECF 中序遍历:DBEAFC 后序遍历:DEBFCA 层次遍历:ABCDEF UVA 112  Tree Summing 题目:给你一个数和一棵树,问是否存在根到叶子的路径使得路径上的数字和与已知数相等. 注意数据中可能有负数 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #i

UVA - 10250 - The Other Two Trees (简单计算几何)

UVA - 10250 The Other Two Trees Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Submit Status Description Problem E The Other Two Trees Input: standard input Output: standard output Time Limit: 2 seconds You have a quadrilateral