zoukankan      html  css  js  c++  java
  • 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了,唉,怎么总感觉读不懂题目呢 ...

  • 相关阅读:
    poj 1222 EXTENDED LIGHTS OUT (高斯消元 )
    poj 2187 Beauty Contest (凸包: 最远点对,最长直径 , 旋转卡壳法)
    poj 1408 Fishnet (几何:线段相交 + 叉积 求面积 )
    poj 1228 Grandpa's Estate ( 凸包 )
    高斯消元 模版
    poj 1830 开关问题 (高斯消元 )
    poj 1113 Wall (凸包:周长)
    旋转卡壳算法
    poj 1681 Painter's Problem (高斯消元 )
    字符串相关处理
  • 原文地址:https://www.cnblogs.com/xiaobaibuhei/p/3042363.html
Copyright © 2011-2022 走看看