首页 > 代码库 > Undraw the Trees UVA 10562

Undraw the Trees UVA 10562

说说:

这道题略坑,好久没做过这么坑的题目了QAQ。这题初看挺复杂的,其实就是个树的遍历问题而已。首先题目给你类似如下的一个结构:

    A
    |
--------
B  C   D
   |   |
 ----- -
 E   F G

这其实是一棵树。‘|’,‘-’可以看成是树干。然后节点字符是除‘|’,‘-’,‘#’,‘ ’以外的其他可显示的字符。若一个节点有子节点,则其正下方的字符为‘|’,且接下去一行‘-’覆盖的范围是它的孩子节点所在的范围。最后整棵树的输出形式是:(A(B()C(E()F())D(G())))。解法其实很简单,把整棵树读入,然后遍历,判断一个节点有无子节点,有则找出范围,然后找到相应节点,再递归,这样就OK了。这次在这道题上花了这么多时间真的是想当然了。因为题目中在子节点所在的行是没有非法字符的,所以我在搜索子节点时只要判断不是空格符,那就是子节点的字符。结果测试一点问题没有,但是就是AC不了。以后真的要注意这样的问题了!

源代码:

#include <stdio.h>
#include <string.h>
#define MAXN 200+5
#define illegal(s) (s!='-'&&s!='|'&&s!=' '&&s!='#')//判断是否为合法节点

char tree[MAXN][MAXN];
int n;

void search(int,int);

int main(){
  int T,i;
  char c;
 // freopen("data","r",stdin);
  scanf("%d",&T);
  getchar();
  while(T--){
    n=0;
    while(gets(tree[n]))
      if(tree[n][0]=='#')
        break;
      else 
        n++;

    putchar('(');
    for(i=0;i<strlen(tree[0]);i++)
      if(illegal(tree[0][i])){
       search(i,0);
       break;
     }
    
    printf(")\n");
  }

  return 0;
}

void search(int pos,int deepth){
  int i,leftmost,rightmost;

  putchar(tree[deepth][pos]);
  if(deepth==n-1||tree[deepth+1][pos]!='|'){//判断有无子树
    printf("()");
    return;  
  }
  leftmost=pos;//子树的左边界
  while(tree[deepth+2][leftmost]=='-')
    leftmost--;
  leftmost++;
  
  rightmost=pos;//子树的右边界
  while(tree[deepth+2][rightmost]=='-')
    rightmost++;
  rightmost--;

  putchar('(');
  for(i=leftmost;i<=rightmost&&i<strlen(tree[deepth+3]);i++)
    if(illegal(tree[deepth+3][i]))//合法字符即为子节点
     search(i,deepth+3);
  putchar(')');

  return;
}


Undraw the Trees UVA 10562