Fork me on GitHub

Uva 10562 - Undraw the Trees

Problem D
Undraw the Trees 
Input: Standard Input

Output: Standard Output

Time Limit: 2 Seconds

 

Professor Homer has been reported missing. We suspect that his recent research works might have had something to with this. But we really don't know much about what he was working on! The detectives tried to hack into his computer, but after hours of failed efforts they realized that the professor had been lot more intelligent than them. If only they could realize that the professor must have been absent minded they could get the clue rightaway. We at the crime lab were not at all surprised when the professor's works were found in a 3.5" floppy disk left inside the drive.

The disk contained only one text file in which the professor had drawn many trees with ASCII characters. Before we can proceed to the next level of investigation we would like to match the trees drawn with the ones that we have in our database. Now you are the computer geek -- we leave this trivial task for you. Convert professor's trees to our trees.

Professor's Trees

The first line of the input file (which you can assume comes from standard input) contains the number of trees, T (1 <= T <= 20) drawn in the file. Then you would have T trees, each ending with a single hash ('#') mark at the beginning of the line. All the trees drawn here are drawn vertically in top down fashion. The labels of each of node can be any printable character except for the symbols '-''|'' ' (space) and '#'. Every node that has children has a '|' symbol drawn just below itself. And in the next line there would be a series of '-' marks at least as long as to cover all the immediate children. The sample input section will hopefully clarify your doubts if there is any. No tree drawn here requires more than 200 lines, and none of them has more than 200 characters in one line.

Our Trees

Our trees are drawn with parenthesis and the node labels. Every subtree starts with an opening parenthesis and ends with a closing parenthesis; inside the parenthesis the node labels are listed. The sub trees are always listed from left to right. In our database each tree is written as a single string in one line, and they do not contain any character except for the node labels and the parenthesis pair. The node labels can be repeated if the original tree had such repetitions.

 

 

             Sample Professor’s Trees      Corresponding Our Trees

2

    A

    |

--------

B  C   D

   |   |

 ----- -

 E   F G

#

e

|

----

f g

#

(A(B()C(E()F())D(G())))

(e(f()g()))

 


Problemsetter: Monirul Hasan, Member of Elite Problemsetters' Panel

 

#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define MAXN 220
typedef struct MTree{
    char value;
    int len;
    struct MTree *horizon, *vectial;
}MTree, *MiscTree;

char input[MAXN][MAXN];

void InitTree(MiscTree& Tree)
{//方便起见,函数的作用是初始化一个节点
    Tree = (MiscTree)malloc(sizeof(MTree));
    Tree->value = ' ';
    Tree->len = 0;
    Tree->horizon = Tree->vectial = NULL;
    return;
}

void Traverse(MiscTree& Tree, char (*from)[MAXN], int current, int last, int choice1, int choice2, int choice3)
{//将数组转化成树的函数,两种情况的判断
    int len = strlen(from[current]);
    switch(current%3)
    {
        case 0:
            {
                    int i, flag = 1;
                    MiscTree node = NULL, front = NULL;
                    for(i=choice2; i<len && i<=choice3; ++i)
                    {
                        if(from[current][i] != ' ')
                        {
                            InitTree(node);
                            node->value = from[current][i];
                            
                            if(flag)
                            {
                                flag = 0;
                                Tree = node;
                            }
                            else
                            {
                                front->vectial = node;    
                            }
                            
                            if(current+1 < last && input[current+1][i] == '|')
                            {
                                choice1 = i;
                                Traverse(node->horizon, from, current+1, last, choice1, choice2, choice3);
                            }
                            front = node;
                        }
                }
                
                break;
            }
        case 1:
            {
                int left, right;
                len = strlen(from[current+1]);
                for(left=choice1; left >= 0 && from[current+1][left] == '-'; --left);
                if(left < 0) left++;
                for(right=choice1; right<len && from[current+1][right] == '-'; ++right);
                if(right >= len) right--;
                choice2 = left, choice3 = right;
                Traverse(Tree, from, current+2, last, choice1, choice2, choice3);
                break;
            }
        case 2:
            {
                printf("\nerror!\n");
                break;
            }
    }
    return;
}

void printTree(MiscTree& Tree)
{//根据原始树输出需要输出的形式的函数,也就是深度优先遍历
    MiscTree front, freenode;
    front = freenode = NULL;
    for(front = Tree; front != NULL; front = front->vectial)
    {
        if(front == Tree) printf("(");
        else free(freenode);
        printf("%c", front->value);
        if(front->horizon != NULL) 
            printTree(front->horizon);
        else printf("()");
        if(front->vectial == NULL) printf(")");
        freenode = front;
    }
    return;
}

int main()
{

    int T, n, len;
    int choice[3], p;
    MiscTree Tree = NULL;
    scanf("%d", &T);
    getchar();
    while(T--)
    {
        for(n=0; fgets(input[n], MAXN, stdin) != NULL; ++n)
        {//处理fgets函数带来的副作用
            len = strlen(input[n]);
            if(input[n][len-1] == '\n') input[n][len-1] = '\0';
            else input[n][len] = '\0';
            if(strcmp(input[n], "#") == 0) break; //n = len + 1
        }
        if(n == 0) printf("()"); //特判
        else 
        {
            Traverse(Tree, input, 0, n, 0, 0, strlen(input[0])-1);
            printTree(Tree);
        }
        printf("\n");
    }
    return 0;
}

解题思路:

对于我来说是建立 兄弟儿子数,即在一个节点中放两个指针,一个为horizon指向它的孩子节点一个指向它的兄弟节点,然后来个深度遍历就行了

注意输入为空树的情况,为此贡献了两次WA

posted @ 2013-03-27 08:42  Gifur  阅读(285)  评论(0编辑  收藏  举报
TOP