UVa 10562 Undraw the Trees 看图写树

Posted 仰望高端玩家的小清新

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVa 10562 Undraw the Trees 看图写树相关的知识,希望对你有一定的参考价值。

 

转载请注明:

 

仰望高端玩家的小清新 http://www.cnblogs.com/luruiyuan/

 

题目大意:

题目传送门:UVa 10562  Undraw the Trees

给定字符拼成的树,将这些树转换成特定的括号表示的树

 

思路:

首先,观察样例,可以发现就是先序遍历的顺序,因此可以确定dfs

但是,还有几个地方需要考虑:

  1.    同一级的结点,在同一级的括号中
  2. 由于顺序满足先序遍历,因此不需要存储树的括号表示法,更不需要构建树,直接在遍历过程中输出即可。
  3. 空树:即输入为:# 时的树的处理,我不建议在此进行特判,因为本题的条件非常简单,完全可以把这个情况纳入普通情况进行处理,详见代码 27行 和 32行。
  4. 关于数组初始化的问题:这里数组必须初始化,我一开始为了效率不想初始化,但是马上就wa了,其原因在于(我个人推测),存在相对刁钻的数据,使得上一次的输入的tree中 ‘|’ 符号出现在了本次 tree 中某一行的 \'\\0\' 之后,这样的话,在本次 tree 做 dfs 时,由于找到了上一次 tree 的 \'|\' 而导致读取到了上一次 tree 的数据。
  5. 森林,有可能某种情况下,可以给出多个根的树,这样就成为了一个森林,需要考虑多根情况。
  6. "----"中我们其实不需要显式找出其右边界,只要知道左边界即可。
  7. 输出数据格式的问题:这里必须吐槽UVA的测试数据,原本我的输出是最后一行不再输出换行符,没想到UVA给我判了wa,把对最后一行的特判去掉后,最后一行也输出换行,才最终ac,出题人有点不注意细节啊,必须批评一波。
  8. 其他 trick:比如用 valid_node 函数中,用字符串匹配代替 if else;读取 tree 时通过 while 循环一行完成读取,而不必写成函数徒增复杂度;使用 fgets 和 sscanf 来读取含有多余空白符的数字。
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 
 5 const int SIZE = 200 + 10;
 6 char tree[SIZE][SIZE];
 7 
 8 int num = 0; // tree num
 9 int cur = 0; // cur num of row in tree
10 
11 bool valid_node(char ch);
12 void dfs_tree(int row, int col);
13 
14 int main(){
15     // use fgets() and sscanf() to read white char and then remove them.
16     fgets(tree[0], SIZE, stdin);
17     sscanf(tree[0], "%d", &num);
18     while(num--){
19         // read tree
20         cur = 0;
21         // memset is compulsory because the \'|\' behind the \'\\0\' of the last tree will
22         // have a bad influence on current tree
23         memset(tree, 0, sizeof(tree));
24         // use fgets() instead of gets() to read tree in order to avoid overflow
25         while(fgets(tree[cur], SIZE, stdin) != NULL && tree[cur][0] != \'#\')cur++;
26         // dfs - for the condition of forest
27         printf("(");
28         for(int i=0; tree[0][i]; i++)
29             if(valid_node(tree[0][i]))
30                 dfs_tree(0, i);
31         // postprocess. If we use "if(num > 0)puts("");", it will cause "wrong answer"
32         printf(")\\n");
33     }
34 }
35 
36 bool valid_node(char ch){
37     return strchr("-| #\\n", ch) == NULL;  // we need add \'\\n\' because fegets() will read the \'\\n\' at end of each line to the tree.
38 }
39 
40 void dfs_tree(int row, int col){
41     printf("%c(", tree[row][col]);  // print root of the tree, and then print \'(\'
42     if(row < cur && tree[++row][col] == \'|\'){
43         int i=col;
44         row++;
45         while(i - 1 >= 0 && tree[row][i-1] == \'-\')i--; //  left bouder of "---"
46         for(;tree[row][i] == \'-\'; i++)
47             if(valid_node(tree[row+1][i])) dfs_tree(row+1, i);
48     }
49     printf(")");
50 }

 

啦啦啦,今天就到这里啦~改天见*★,°*:.☆( ̄▽ ̄)/$:*.°★* 。

以上是关于UVa 10562 Undraw the Trees 看图写树的主要内容,如果未能解决你的问题,请参考以下文章

UVa 10562 Undraw the Trees 看图写树

Undraw the Trees (Uva 10562)

Uva10562

6-17 看图写树 uva10562

UVa 10562 看图写树

Flutter Undraw Widget - 更新后的PictureStream错误