UVa 699 - The Falling Leaves

  给一个先序遍历序列,构建一个二叉树,在垂直方向上给二叉树分列,计算每一列的和。

  开始我按照这个序列构建了一个二叉树,然后遍历进行计算,代码如下:

View Code
  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 
  5 const int maxn = 199;
  6 const int mid = 100;
  7 
  8 struct Node 
  9 {
 10     int value;
 11     Node *left, *right;
 12 };
 13 
 14 Node * new_node()
 15 {
 16     Node * u = (Node *)malloc(sizeof(Node));
 17     if(u)
 18     {
 19         u->value = 0;
 20         u->left = u->right = NULL;
 21     }
 22     return u;
 23 }
 24 
 25 int first;
 26 
 27 int build(Node * u)
 28 {
 29     int x;
 30     scanf("%d", &x);
 31     //if the first data of the case is -1, return 0;
 32     if(first)
 33     {
 34         first = 0;
 35         if(x == -1)   return 0;
 36     }
 37     u->value = x;
 38     if(x > 0)
 39     {
 40         if(!u->left)   u->left = new_node();
 41         build(u->left);
 42         if(!u->right)   u->right = new_node();
 43         build(u->right);
 44     }
 45     return 1;
 46 }
 47 
 48 void remove_tree(Node * u)
 49 {
 50     if(!u)   return;
 51     remove_tree(u->left);
 52     remove_tree(u->right);
 53     free(u);
 54 }
 55 
 56 int n, ans[maxn];
 57 int left, right;
 58 
 59 void traversal(Node * p, int step)   //preoder traversal
 60 {
 61     //step represent the displacement relative to root node
 62     if(p->value > 0) 
 63     {
 64         ans[mid+step] += p->value;
 65         if(mid + step < left)   left = mid + step;
 66         if(mid + step >= right)   right = mid + step + 1;
 67     }
 68     if(p->left)   traversal(p->left, step-1);
 69     if(p->right)   traversal(p->right, step+1);
 70 }
 71 
 72 int main()
 73 {
 74 #ifdef LOCAL
 75     freopen("in", "r", stdin);
 76 #endif
 77     int kase = 0;
 78     while(1)
 79     {
 80         Node * root;
 81         root = new_node();
 82         first = 1;
 83         left = 100;
 84         right = 101;
 85         if(!build(root))   break;
 86         Node * p = root;
 87         memset(ans, 0, sizeof(ans));
 88         traversal(root, 0);
 89         remove_tree(root);
 90         printf("Case %d:\n", ++kase);
 91         for(int i = left; i < right; i++)
 92         {
 93             printf("%s", i == left ? "" : " ");
 94             printf("%d", ans[i]);
 95         }
 96         printf("\n\n");
 97     }
 98     return 0;
 99 }
100     

  后来有看了别人代码,忽然发现,既然这个序列是按先序遍历给的,就没有必要构建二叉树了,可以直接计算啊,又用递归写了一个,上面那个时间0.06s,这个0.052s,差别不是很大。代码如下:

View Code
 1 #include <cstdio>
 2 #include <cstring>
 3 
 4 const int maxn = 199;
 5 const int mid = 100;
 6 int ans[maxn];
 7 int left, right;    //the left and right boundary
 8 int first;
 9 
10 int tree_dfs(int step)
11 {
12     int x;
13     scanf("%d", &x);
14     if(first)
15     {
16         first = 0;
17         if(x == -1)   return 0;
18     }
19     if(x > 0)
20     {
21         ans[mid+step] += x;
22         if(mid + step < left)   left = mid + step;
23         if(mid + step >= right)   right = mid + step + 1;
24         tree_dfs(step-1);
25         tree_dfs(step+1);
26     }
27     return 1;
28 }
29 
30 int main()
31 {
32 #ifdef LOCAL 
33     freopen("in", "r", stdin);
34 #endif
35     int kase = 0;
36     while(1)
37     {
38         first = 1;
39         left = 100;
40         right = 101;
41         memset(ans, 0, sizeof(ans));
42         if(!tree_dfs(0))   break;
43         printf("Case %d:\n", ++kase);
44         for(int i = left; i < right; i++)
45         {
46             printf("%s", i == left ? "" : " ");
47             printf("%d", ans[i]);
48         }
49         printf("\n\n");
50     }
51     return 0;
52 }

  刚开始没注意结果不会超过80个,以为是数据输出的要求,超过80要换行呢,开了一个大数组,对边界各种处理,最后还WA了,唉,怎么总感觉读不懂题目呢 ...

posted @ 2013-04-25 13:28  xiaobaibuhei  阅读(238)  评论(0编辑  收藏  举报