• 二叉树基础练习


    前序遍历(先根遍历):根,左子树,右子树

    中序遍历:左子树,根,右子树
    后序遍历:左子树,右子树,根

    先序遍历:ABDECF

    中序遍历:DBEAFC

    后序遍历:DEBFCA

    层次遍历:ABCDEF

    UVA 112  Tree Summing

    题目:给你一个数和一棵树,问是否存在根到叶子的路径使得路径上的数字和与已知数相等。

    注意数据中可能有负数

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<string>
     7 #include<cmath>
     8 #include<vector>
     9 #include<stack>
    10 #include<map>
    11 using namespace std;
    12 #define CLR(a,b) memset((a),(b),sizeof((a)))
    13 #define lson id*2
    14 #define rson id*2+1
    15 typedef long long ll;
    16 typedef unsigned long long ull;
    17 typedef pair<int, int>pii;
    18 const int inf = 0x3f3f3f3f;
    19 int n;
    20 char input() {
    21     char c;
    22     scanf("%c", &c);
    23     while(c == ' ' || c == '
    ') scanf("%c", &c);
    24     return c;
    25 }
    26 int solve(int v, int *leaf) {
    27     int l = 0, r = 0, f = 0;
    28     int value;
    29     scanf("%d", &value);
    30     char c = input();
    31 
    32     if(c == '(') {
    33         if(solve(v - value, &l)) f = 1;
    34         c = input();
    35         if(solve(v - value, &r)) f = 1;
    36         c = input();
    37         if(l && r && v == value) f = 1;
    38     }
    39     else *leaf = 1;
    40 
    41     return f;
    42 }
    43 int main() {
    44     int t;
    45     while(~scanf("%d", &n)) {
    46         input();
    47         if(solve(n, &t)) puts("yes");
    48         else puts("no");
    49     }
    50     return 0;
    51 }
    50ms

    UVA 548 Tree

    题意:给一棵带权树的中序和后序遍历,找一个叶子使得它到根的路径的权值尽可能小,若有多解取叶子权值小的。

    题解:后序遍历的最后一个字符就是根,然后在中序遍历中找到根,从而找出左右子树的节点,递归构造左右子树。再DFS遍历找最优解。

    yy:string和stringstream用法总结

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<string>
     6 #include<sstream>
     7 using namespace std;
     8 #define CLR(a,b) memset((a),(b),sizeof((a)))
     9 #define lson id*2
    10 #define rson id*2+1
    11 typedef long long ll;
    12 typedef unsigned long long ull;
    13 const int inf = 0x3f3f3f3f;
    14 const int N = 1e5+5;
    15 int lch[N], rch[N], in_order[N], post_order[N];
    16 int n;
    17 int build(int l1, int r1, int l2, int r2) {
    18     if(l1 > r1) return 0; //空树返回0
    19     int rt = post_order[r2]; //
    20     int cnt, p = l1;
    21     while(in_order[p] != rt)  p++;
    22     cnt = p - l1; //左子树节点个数
    23     lch[rt] = build(l1, p-1, l2, l2+cnt-1);//递归构造左子树
    24     rch[rt] = build(p+1, r1, l2+cnt, r2-1);//递归构造右子树
    25     return rt;//返回根
    26 }
    27 int best, best_sum;
    28 void dfs(int u, int sum) {
    29     sum += u;
    30     if(!lch[u] && !rch[u]) { //叶子
    31         if(sum < best_sum || (sum == best_sum && u < best)) {
    32             best_sum = sum;
    33             best = u;
    34         }
    35     }
    36     if(lch[u]) dfs(lch[u], sum);
    37     if(rch[u]) dfs(rch[u], sum);
    38 }
    39 bool input(int *a) {
    40     string line;
    41     if(!getline(cin, line)) return false;
    42     stringstream ss(line);
    43     int x;
    44     n = 0;
    45     while(ss >> x) a[n++] = x;
    46     return n > 0;
    47 }
    48 int main() {
    49     while(input(in_order)) {
    50         input(post_order);
    51         build(0, n-1, 0, n-1);
    52         best_sum = inf;
    53         dfs(post_order[n-1], 0);
    54         printf("%d
    ", best);
    55     }
    56     return 0;
    57 }
    80ms

    UVA 297 Quadtrees  四分树)

    求两棵四分树合并之后黑色像素的个数。(给出两棵四分树的先序遍历,p表示中间节点,f表示黑色,e表示白色)

     

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<string>
     6 #include<sstream>
     7 using namespace std;
     8 #define CLR(a,b) memset((a),(b),sizeof((a)))
     9 #define lson id*2
    10 #define rson id*2+1
    11 typedef long long ll;
    12 typedef unsigned long long ull;
    13 const int inf = 0x3f3f3f3f;
    14 const int N = 1024+5;
    15 const int len = 32+5;
    16 char s[N];
    17 int vis[len][len];
    18 int ans;
    19 void dfs(int &cnt, int x, int y, int L) {
    20     char c = s[cnt++];
    21     if(c == 'p') {
    22         dfs(cnt, x, y, L / 2); //1
    23         dfs(cnt, x + L/2, y, L / 2); //2
    24         dfs(cnt, x + L/2, y + L/2, L / 2); //3
    25         dfs(cnt, x, y + L/2, L / 2); //4
    26     }
    27     else if (c == 'f') {
    28         for(int i = x; i < x+L; ++i) {
    29             for(int j = y; j < y+L; ++j) {
    30                 if(!vis[i][j]) {
    31                     vis[i][j] = 1;
    32                     ans++;
    33                 }
    34             }
    35         }
    36     }
    37 }
    38 int main() {
    39     int t;
    40     scanf("%d", &t);
    41     while(t--) {
    42         CLR(vis, 0);
    43         ans = 0;
    44 
    45         scanf("%s", s);
    46         int cnt = 0;
    47         dfs(cnt, 0, 0, 32);
    48 
    49         scanf("%s", s);
    50         cnt = 0;
    51         dfs(cnt, 0, 0, 32);
    52         printf("There are %d black pixels.
    ", ans);
    53     }
    54     return 0;
    55 }
    0ms

    UVA 712 S-Trees

    题意:给出一个不超过7层的满二叉树,然后给出满二叉树的叶子节点的值(0或1),给出路径(0往左走,1往右走)并输出每条路径到达叶子节点的值。

    题解:0:L=L*2;  1:L=L*2+1; 叶子L=L-2^n+1

    (注意输入格式%1d)

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<string>
     6 #include<sstream>
     7 using namespace std;
     8 #define CLR(a,b) memset((a),(b),sizeof((a)))
     9 #define lson id*2
    10 #define rson id*2+1
    11 typedef long long ll;
    12 typedef unsigned long long ull;
    13 const int inf = 0x3f3f3f3f;
    14 const int N = 8;
    15 char s[30];
    16 int a[1<<N], ans[1<<N];
    17 int n, m;
    18 int main() {
    19     int k = 1;
    20     while(~scanf("%d", &n), n) {
    21         getchar();//吸收回车
    22         cin.getline(s, 25, '
    ');//第二行无用
    23         for(int i = 1; i <= (1<<n); ++i)
    24             scanf("%1d", &a[i]); //注意输入格式 存叶子值
    25         scanf("%d", &m);
    26         int o;
    27         for(int i = 0; i < m; ++i) {
    28             int x = 1;//
    29             for(int j = 1; j <= n; ++j) {
    30                 scanf("%1d", &o);
    31                 x = 2*x + o;
    32             }
    33             x -= ((1<<n)-1);//叶子结点
    34             ans[i] = a[x];
    35         }
    36         printf("S-Tree #%d:
    ", k++);
    37         for(int i = 0; i < m; ++i)
    38             printf("%d", ans[i]);
    39         printf("
    
    ");
    40     }
    41     return 0;
    42 }
    0ms

    UVA 699 The Falling Leaves

    题意: 给一棵树,每棵树有一个叶子,叶子的值是点权,求叶子垂直落下后, (同一个方向的形成一堆),求每堆叶子的总权值。

    注意:一行数据不一定是一颗完整的树 。

    题解:这里根从N/2开始,-1,+1进行建树,先序遍历

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<string>
     6 #include<sstream>
     7 using namespace std;
     8 #define CLR(a,b) memset((a),(b),sizeof((a)))
     9 #define lson id*2
    10 #define rson id*2+1
    11 typedef long long ll;
    12 typedef unsigned long long ull;
    13 const int inf = 0x3f3f3f3f;
    14 const int N = 210;
    15 int a[N], x;
    16 void dfs(int pos, int x) {
    17     a[pos] += x;
    18     scanf("%d", &x);
    19     if(x != -1)
    20         dfs(pos-1, x);//左子树
    21     scanf("%d", &x);
    22     if(x != -1)
    23         dfs(pos+1, x);//右子树
    24 }
    25 int main() {
    26     int k = 1;
    27     while(1) {
    28         int f = 0;
    29         CLR(a, 0);
    30         scanf("%d", &x);
    31         if(x == -1) break;
    32         dfs(N/2, x);
    33         printf("Case %d:
    ", k++);
    34         for(int i = 0; i < N; ++i) {
    35             if(a[i]) {
    36                 if(f) printf(" %d", a[i]);
    37                 else { f = 1; printf("%d", a[i]); }
    38             }
    39         }
    40         printf("
    
    ");
    41     }
    42     return 0;
    43 }
    10ms

    UVA 839 Not so Mobile

    题意:每个秤都是一个树的结构,已知秤两边的重量和到支点的距离,问秤能否平衡

    题解:dfs判断每个节点是否都平衡。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<string>
     6 #include<sstream>
     7 using namespace std;
     8 #define CLR(a,b) memset((a),(b),sizeof((a)))
     9 #define lson id*2
    10 #define rson id*2+1
    11 typedef long long ll;
    12 typedef unsigned long long ull;
    13 const int inf = 0x3f3f3f3f;
    14 const int N = 8;
    15 bool dfs(int &s) {
    16     int wl, dl, wr, dr, a=1, b=1;
    17     scanf("%d%d%d%d", &wl, &dl, &wr, &dr);
    18     if(!wl) a = dfs(wl);
    19     if(!wr) b = dfs(wr);
    20     s = wl + wr; //为上层传值
    21     if(a && b && wl*dl == wr*dr) return 1;
    22     return 0;
    23 }
    24 int main() {
    25     int t, x;
    26     scanf("%d", &t);
    27     while(t--) {
    28         x = 0;
    29         if(dfs(x)) puts("YES");
    30         else puts("NO");
    31         if(t) puts("");
    32     }
    33     return 0;
    34 }
    20ms

    UVA 10562 Undraw the Trees

    题意:根据题目所给出的图写出多叉树。

    题解:每三行看作一组数据,先序遍历。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<string>
     6 #include<sstream>
     7 using namespace std;
     8 #define CLR(a,b) memset((a),(b),sizeof((a)))
     9 #define lson id*2
    10 #define rson id*2+1
    11 typedef long long ll;
    12 typedef unsigned long long ull;
    13 const int inf = 0x3f3f3f3f;
    14 const int N = 205;
    15 char s[N][N];
    16 int n;
    17 void dfs(int a, int b, int i) {
    18     for(int j = a; j < b; ++j) {
    19         if(s[i][j] == ' ' || s[i][j] == '') continue;
    20         putchar(s[i][j]);
    21         putchar('(');
    22         if(i+1 < n && s[i+1][j] == '|') {
    23             int l, r;
    24             for(l = j; l >= 0 && s[i+2][l] == '-'; l--) ;
    25             int len = strlen(s[i+2]);
    26             for(r = j; r < len && s[i+2][r] == '-'; r++) ;
    27             dfs(l+1, r, i+3);
    28         }
    29         putchar(')');
    30     }
    31 }
    32 int main() {
    33     int t;
    34     scanf("%d%*c", &t);
    35     while(t--) {
    36         CLR(s, 0);
    37         n = 0;
    38         while(cin.getline(s[n], N, '
    ')) {
    39             if(strcmp(s[n], "#") == 0)
    40                 break;
    41             n++;
    42         }
    43         putchar('(');
    44         if(n) dfs(0, strlen(s[0]), 0);
    45         putchar(')');
    46         puts("");
    47     }
    48     return 0;
    49 }
    0ms

    UVA 536 Tree Recovery

    题意:给出树的前序遍历和中序遍历,求此树的后序遍历。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<string>
     6 #include<sstream>
     7 using namespace std;
     8 #define CLR(a,b) memset((a),(b),sizeof((a)))
     9 #define lson id*2
    10 #define rson id*2+1
    11 typedef long long ll;
    12 typedef unsigned long long ull;
    13 const int inf = 0x3f3f3f3f;
    14 const int N = 26+5;
    15 char pre_order[N], in_order[N];
    16 void dfs(int l1, int r1, int l2, int r2) {
    17     if(l1 > r1) return;
    18     int p = l2;
    19     int rt = pre_order[l1];
    20     while(in_order[p] != pre_order[l1]) p++;
    21     int cnt = p - l2;
    22     dfs(l1+1, l1+cnt, l2, p-1);
    23     dfs(l1+cnt+1, r1, p+1, r2);
    24     printf("%c", in_order[p]);
    25 }
    26 int main() {
    27     while(~scanf("%s %s", pre_order, in_order)) {
    28         int len = strlen(pre_order)-1;
    29         dfs(0, len, 0, len);
    30         puts("");
    31     }
    32     return 0;
    33 }
    0ms
  • 相关阅读:
    一次维护经历
    网络线用色环表示
    ★★★错误终于抓到了★★★
    帮别人装IBM本本花了两天
    好记忆不如烂笔头
    凌晨完成的内容
    好久没上网了!
    oseye问答和博文评论通知的设计思路
    简单四步设置debian的vps安全防护
    javascript 的call()与apply()的应用与区别
  • 原文地址:https://www.cnblogs.com/GraceSkyer/p/6498434.html
Copyright © 2020-2023  润新知