刘汝佳 算法竞赛-入门经典 第二部分 算法篇 第六章 2(Binary Trees)

112 - Tree Summing

   题目大意:给出一个数,再给一颗树,每个头节点的子树被包含在头节点之后的括号里,寻找是否有从头节点到叶子的和与给出的数相等,如果有则输出yes,没有输出no!

  解题思路:按照括号匹配的原则,调用栈,求从头节点到叶子节点的和!

  解题代码:

 1 //Author    :Freetion
 2 //file        :112 - Tree Summing
 3 
 4 #include <stdio.h>
 5 #include <iostream>
 6 #include <stack>
 7 #include <string.h>
 8 using namespace std;
 9 
10 #define Local
11 int main()
12 {
13 #ifdef Local
14     freopen ("data.in", "r", stdin);
15     freopen ("data.out", "w", stdout);
16 #endif
17     stack <char> bracket;
18     int num[100000];
19     int mat, cun, wei, sum;
20     bool flag = false, zh = true;
21     while (~scanf ("%d", &mat))
22     {
23         flag = false;
24         char ch;
25         cun = sum = wei = 0;
26         while (!bracket.empty())
27             bracket.pop();
28         while (cin >> ch)
29         {
30             if (ch == '(')
31             {
32                 wei = 0;
33                 zh = true;
34                 bracket.push(ch);
35             }
36             else if (ch == ')')
37             {
38                 wei = 0;
39                 zh = true;
40                 bracket.pop();
41                 if (bracket.size() == cun)
42                 {
43                     for (int i = 0; i <= cun; i ++)
44                         sum += num[i];
45                     if (sum == mat)
46                         flag = true;
47                     else sum = 0;
48                 }
49                 if (bracket.empty())
50                     break;
51             }
52             else
53             {
54                 if (ch == '-')
55                     zh = false;
56                 else if(wei)
57                 {
58                     if (!zh)
59                         num[cun] = -num[cun];
60                     num[cun] = 10*num[cun] + ch - '0';
61                     if (!zh)
62                         num[cun] = -num[cun];
63                 }
64                 else
65                 {
66                 
67                     cun = bracket.size() - 1;
68                     num[cun] = ch - '0';
69                     wei ++;
70                     if (!zh)
71                         num[cun] = -num[cun];
72                 }
73                 
74             }
75         }
76         if (flag)
77             printf ("yes\n");
78         else printf ("no\n");
79     }
80     return 0;
81 }
View Code

 

548 - Tree

  题目大意:给出一颗二叉树的中序遍历和后序遍历,求从头节点到叶子节点的最小和,并且将获得该最小和的路径的叶子节点的值输出。

  解题思路:根据中序遍历和后序遍历递归建树,找到最小和,并保存该路径的叶子节点的值!

  解题代码:

  1 //Author    :Freetion
  2 //file        :548 - Tree ¸ù¾Ý¶þ²æÊ÷ÖÐÐò±éÀú½á¹ûÓëºóÐò±éÀú½á¹ûÖع¹¶þ²æÊ÷
  3 
  4 #include <stdio.h>
  5 #include <string.h>
  6 #include <iostream>
  7 #include <sstream>  
  8 using namespace std;
  9 
 10 //#define Local
 11 
 12 struct node
 13 {
 14     int min_sum;
 15     int min_leaf;
 16 }Min;
 17 
 18 void find_minsum(const int& mid, int len_mid, const int& back, int len_back, int sum)
 19 {
 20     if (len_back == 0)
 21     { 
 22     //    cout << " ( ) ";
 23         return ;
 24     }
 25     if (len_back == 1)
 26     {
 27         sum += *(&back);
 28         if (sum < Min.min_sum)
 29         {
 30             Min.min_sum = sum;
 31             Min.min_leaf = *(&back);
 32         }
 33         else if (sum == Min.min_sum)
 34         {
 35             if (back < Min.min_leaf)
 36                 Min.min_leaf = *(&back);
 37         }
 38     //    cout << " ( " << *(&back)<< " ) ";
 39         return ;
 40     }
 41     int k = -1;
 42     for (int i = 0; i < len_mid; i ++)
 43         if (*(&mid+i) == *(&back+(len_back-1)))
 44         {
 45             k = i;
 46             break;
 47         }
 48     sum += *(&back+(len_back-1));
 49 //    cout << " ( " << *(&back+(len_back-1));
 50     find_minsum(*(&mid), k, *(&back), k, sum);
 51     
 52     find_minsum(*(&mid+k+1), len_mid-k-1, *(&back + k), len_mid-k-1, sum);
 53 //    cout << " ) ";
 54 }
 55 
 56 int main()
 57 {
 58 #ifdef Local
 59     freopen("data.in", "r", stdin);
 60     freopen("data.out", "w", stdout);
 61 #endif
 62     int mid[10005], back[10005];
 63     string tmp;
 64     int cun_mid, cun_back;
 65     string str;
 66     while (getline(cin, str))
 67     {
 68         Min.min_sum = 0x3fffffff;
 69         cun_mid = cun_back = 0;
 70         
 71         istringstream in(str);
 72         while (in >> tmp)
 73         {
 74             int len = tmp.size();
 75             mid[cun_mid] = 0;
 76             for (int i = 0; i < len; i ++)
 77             {
 78                 mid[cun_mid] = 10 * mid[cun_mid] + tmp[i] - '0';
 79             }
 80             cun_mid ++;
 81         }
 82         
 83         getline(cin, str);
 84         istringstream input(str);
 85         while (input >> tmp)
 86         {
 87             int len = tmp.size();
 88             back[cun_back] = 0;
 89             for (int i = 0; i < len; i ++)
 90             {
 91                 back[cun_back] = 10 * back[cun_back] + tmp[i] - '0';
 92             }
 93             cun_back ++;
 94         }
 95         
 96         find_minsum(*mid, cun_mid, *back, cun_back, 0);
 97     //    cout << endl;
 98         cout << Min.min_leaf << endl;
 99     }
100 }
View Code

 

297 - Quadtrees

  解题思路:递归建树,寻找黑节点,找到后将该节点所占像素累加起来,最后输出!

  解题代码:

  1 //Author    :Freetion
  2 //file        :297 - Quadtrees
  3 
  4 #include <stdio.h>
  5 #include <string>
  6 #include <iostream>
  7 using namespace std;
  8 
  9 struct TREE
 10 {
 11     bool black;
 12     struct TREE *leaf[4];
 13 }tree;
 14 TREE *root1, *root2;
 15 char *q;
 16 int sum;
 17 
 18 TREE* build_tree()
 19 {
 20     TREE *root = new TREE;
 21     root -> black = 0;
 22     if(*q == 'p')
 23     {
 24         for (int i = 0; i < 4; i ++)
 25         {
 26             q ++;
 27             root -> leaf[i] = build_tree();
 28         }
 29     }
 30     else
 31     {
 32         if (*q == 'f')
 33             root -> black = 1;
 34         for (int i = 0; i < 4; i ++)
 35             root -> leaf[i] = NULL;
 36     }
 37     return root;
 38 }
 39 
 40 void print(TREE *root)
 41 {
 42     if (root == NULL)
 43         return;
 44     printf ("(%d", root -> black);
 45     for (int i = 0; i < 4; i ++)
 46         print (root -> leaf[i]);
 47     printf (")");
 48     return ;
 49 }
 50 
 51 void DFS(TREE *root1, TREE *root2, int cen)//cen代表深度
 52 {
 53     if (root1 == NULL && root2 == NULL)
 54         return ;
 55     if (root1 == NULL)
 56     {
 57         if (root2 -> black)
 58         {
 59             sum += (1 << (10 - 2*cen)); 
 60             return;
 61         }
 62         for (int i = 0; i < 4; i ++)
 63             DFS(root1, root2 -> leaf[i], cen + 1);
 64         return ;
 65     }
 66     if (root2 == NULL)
 67     {
 68         if (root1 -> black)
 69         {
 70             sum += (1 << (10 - 2*cen));
 71             return ;
 72         }
 73         for (int i = 0; i < 4; i ++)
 74             DFS(root1 -> leaf[i], root2, cen + 1);
 75         return ;
 76     }
 77     if (root1 -> black || root2 -> black)
 78     {
 79         sum += (1 << (10 - 2*cen));
 80         return ;
 81     }
 82     for (int i = 0; i < 4; i ++)
 83         DFS (root1 -> leaf[i], root2 -> leaf[i], cen + 1);
 84 }
 85 
 86 int main()
 87 {
 88     int T;
 89     scanf ("%d", &T);
 90     getchar();
 91     string tre1, tre2, tresum;
 92     while (T--)
 93     {
 94         sum = 0;
 95         getline(cin, tre1);
 96         getline(cin, tre2);
 97         q = &tre1[0];
 98         root1 = build_tree();
 99         q = &tre2[0];
100         root2 = build_tree();
101 /*
102         print (root1);
103         printf ("\n");
104         print (root2);
105         printf ("\n");
106 */
107         DFS(root1, root2, 0);
108         printf ("There are %d black pixels.\n", sum);
109     }
110 }
View Code

 

712 - S-Trees

  此题Submission error先把代码放这。

 1 //Author    :Freetion
 2 //file        :712 - S-Trees
 3 
 4 #include <stdio.h>
 5 #include <string>
 6 #include <iostream>
 7 #include <algorithm>
 8 using namespace std;
 9 
10 const int max_p = 20;
11 struct cen
12 {
13     string str;
14     int num;
15     bool operator < (const cen c) const
16     {
17         return str < c.str;
18     }
19 };
20 
21 int main()
22 {
23     freopen("data.in", "r", stdin);
24     freopen("data.out", "w", stdout);
25     int leaf[max_p];
26     int n, cas = 1;
27     cen ce[10];
28     while (scanf ("%d", &n) == 1 && n)
29     {
30         printf ("S-Tree #%d:\n", cas ++);
31         for (int i = 0; i < n; i ++)
32             cin >> ce[i].str;
33         for (int i = 0; i < 2*(n+1); i ++)
34             scanf ("%1d", &leaf[i]);
35         int que;
36         scanf ("%d", &que);
37         while (que--)
38         {
39             for (int i = 0; i < n; i ++)
40                 scanf ("%1d", &ce[i].num);
41             sort (ce, ce+n);
42             int node = 1;
43             for (int i = 0; i < n; i ++)
44             {
45                 if (ce[i].num)
46                     node = 2*node + 1;
47                 else node = 2*node;
48             }
49             printf ("%d", leaf[node - (1<<n)]);
50         }
51         printf ("\n\n");
52     }
53 }
View Code

 

699 - The Falling Leaves

  题目大意:给一颗树的先序遍历,-1代表空节点,那么给出的便是满二叉树,求从左到右竖直在一条直线的节点的和,并从左到有输出。子节点与父节点水平距离为1。

  解题思路:先把树存入,后按照节点位置累加和,运用map容器可运用负数作下标,怎很容易保存节点位置。

  解题代码:

 1 //Author    :Freetion
 2 //file        :699 - The Falling Leaves
 3 
 4 #include <stdio.h>
 5 #include <iostream>
 6 #include <string>
 7 #include <map>
 8 using namespace std;
 9 
10 struct node
11 {
12     int num;
13     int pos;
14     node *left, *right;
15 };
16 int in;
17 int Min;
18 int Max;
19 map <int, int> stor;
20 node* build(int pos)
21 {
22     int x;
23     if (scanf ("%d", &x) == -1 || (x == -1 && in == 0))
24         return NULL;
25     in ++;
26     node *root = new node;
27     if (x != -1)
28     {
29         root -> pos = pos;
30         root -> num = x;
31         root -> left = build(pos - 1);
32         Min = (Min < pos - 1) ? Min : pos - 1;
33         root -> right = build(pos + 1);
34         Max = (Max > pos + 1) ? Max : pos + 1;
35     }
36     if (x == -1)
37     {
38         root -> left = NULL;
39         root -> right = NULL;
40     }
41     return root;
42 }
43 
44 void fall_leaf(node *root)
45 {
46     if (root == NULL)
47         return;
48     if (root != NULL)
49     {
50         stor[root -> pos] += root -> num;
51         fall_leaf(root -> left);
52         fall_leaf(root -> right);
53         return;
54     }
55 }
56 
57 int main()
58 {
59 //    freopen("data.in", "r", stdin);
60 //    freopen("data.out", "w", stdout);
61     int cas = 1;
62     while (1)
63     {
64         Min = 0x3fffffff;
65         Max = -0x3fffffff;
66         in = 0;
67         stor.clear();
68         node *root = build(0);
69         if (root == NULL)
70             break;
71 
72         fall_leaf(root);
73         printf ("Case %d:\n", cas ++);
74         for (int i = Min+1; i < Max; i ++)
75             printf ("%d%c", stor[i], (i == Max-1) ? '\n' : ' ');
76         printf ("\n");
77     }
78     
79 }
View Code

 

327 - Evaluating Simple C Expressions

  题目意思很显然。

  解题思路:直接模拟各种运算符结合的情况。

  解题代码:

  1 //Author    :Freetion
  2 //file        :327 - Evaluating Simple C Expressions
  3 
  4 #define Local
  5 #include <iostream>
  6 #include <stdio.h>
  7 #include <string.h>
  8 
  9 int num[200];
 10 char ope[100000];
 11 bool appear[200];
 12 
 13 void give_value()
 14 {
 15     memset(appear, 0, sizeof(appear));
 16     for (int i = 97; i <= 'z'; i ++)
 17         num[i] = i - 96;
 18     return ;
 19 }
 20 
 21 int solve()
 22 {
 23     int ans = 0;
 24     int add = 0, red = 0;
 25     int start = 0;
 26     int len = strlen(ope);
 27     for (int i = 0; i < len; i ++)
 28     {
 29         if (ope[i] == ' ')
 30             continue;
 31         if (ope[i] == '-')
 32         {
 33             red ++;
 34             if (red == 2 && add == 0 && start)
 35             {
 36                 int j = i;
 37                 while (ope[j] == ' ' || ope[j] == '-' || ope[j] == '+')
 38                     j --;
 39                 num[ope[j]] --;
 40                 red = 0;
 41                 start = 0;
 42             }
 43         }
 44         else if (ope[i] == '+')
 45         {
 46             add ++;
 47             if (red == 0 && add == 2 && start)
 48             {
 49                 int j = i;
 50                 while (ope[j] == ' ' || ope[j] == '-' || ope[j] == '+')
 51                     j --;
 52                 num[ope[j]] ++;
 53                 add = 0;
 54                 start = 0;
 55             }
 56         }
 57         else
 58         {
 59             start = 1;
 60             if (add == 1 && red == 2)
 61             {
 62                 num[ope[i]] --;
 63                 ans += num[ope[i]];
 64             }
 65             else if (add == 2 && red == 1)
 66             {
 67                 num[ope[i]] ++;
 68                 ans -= num[ope[i]];
 69             }
 70             else if (add == 0 && red == 1)
 71                 ans -= num[ope[i]];
 72             else if ((add == 3 || add == 2)&& red == 0)
 73             {
 74                 num[ope[i]] ++;
 75                 ans += num[ope[i]];
 76             }
 77             else if (add == 0 && (red == 3 || red == 2))
 78             {
 79                 num[ope[i]] --;
 80                 if (red == 3)
 81                     ans -= num[ope[i]];
 82                 else ans += num[ope[i]];
 83             }
 84             else
 85                 ans += num[ope[i]];
 86             appear[ope[i]] = 1;
 87             add = red = 0;
 88         }
 89     }
 90     return ans;
 91 }
 92 
 93 int main()
 94 {
 95 #ifdef Local
 96     freopen("data.in", "r", stdin);
 97     freopen("data.out", "w", stdout);
 98 #endif
 99     while (gets(ope))
100     {
101         int ans;
102         give_value();
103         printf ("Expression: %s\n", ope);
104         ans = solve();
105         
106         printf ("    value = %d\n", ans);
107         for (int i = 'a'; i <= 'z'; i ++)
108             if (appear[i])
109             printf ("    %c = %d\n", i, num[i]);
110     }
111 }
View Code

 

839 - Not so Mobile

  题目大意:给出一个杠杆,w1,d1,w2,d2,判断杠杆是否平衡,即w1*d1 == w2*d2;如果w1 为 0则说明,左边杠杆下还有杠杆,w2为0亦然。判断所有杠杆是否平衡。

  解题思路:按照输入直接递归判断。

  解题代码:

 1 //Author    :Freetion
 2 //file        :839 - Not so Mobile
 3 
 4 #include <stdio.h>
 5 #include <math.h>
 6 #include <string>
 7 #include <iostream>
 8 using namespace std;
 9 
10 int w1, d1, w2, d2;
11 int flag;
12 
13 int DFS(int w1, int d1, int w2, int d2)
14 {
15     scanf ("%d%d%d%d", &w1, &d1, &w2, &d2);
16     if (w1 == 0)
17         w1 = DFS(w1, d1, w2, d2);
18     if (w2 == 0)
19         w2 = DFS(w1, d1, w2, d2);
20     if (w1*d1 != w2*d2)
21         flag = 0;
22     return (w1 + w2);
23 }
24 
25 int main()
26 {
27     int T;
28     int w1, d1, w2, d2;
29     scanf ("%d", &T);
30     while (T--)
31     {
32         flag = 1;
33         DFS(0, 0, 0, 0);
34         if (flag)
35             printf ("YES\n");
36         else printf ("NO\n");
37         if (T)
38             puts("");
39     }
40     return 0;
41 }
View Code

 

10562 - Undraw the Trees

  题意也很显然。

  解题代码:

 1 //Author    :Freetion
 2 //file        :10562 - Undraw the Trees
 3         #define Local
 4 #include <string>
 5 #include <stdio.h>
 6 #include <iostream>
 7 using namespace std;
 8 
 9 string tree[210];
10 int cun;
11 
12 void DFS(int D, int B)
13 {
14     int i;
15     for (i = B; i >= 0; i --)
16         if (tree[D][i] != '-')
17             break;
18     for (i ++; i < tree[D].size() && tree[D][i] == '-'; i ++)
19     {
20         if (i >= tree[D+1].size())
21             break;
22         if (tree[D+1][i] != ' ' && tree[D+1][i] != '#')
23         {
24             printf ("%c(", tree[D+1][i]);
25             if (D+2 < cun && tree[D+2][i] == '|')
26                 DFS(D+3, i);
27             else printf(")");
28         }
29     }
30     printf (")");
31     return;
32 }
33 
34 int main()
35 {
36 #ifdef Local
37     freopen ("data.in", "r", stdin);
38     freopen ("data.out", "w", stdout);
39 #endif
40     int T;
41     tree[0].clear();
42     for (int i = 0; i < 210; i ++)
43             tree[0] += '-';
44     scanf ("%d", &T);
45     getchar();
46     while (T--)
47     {
48         cun = 1;
49         while (1)
50         {
51             getline(cin, tree[cun]);
52             if (tree[cun][0] == '#')
53                 break;
54             cun ++;
55         }
56         printf ("(");
57         DFS(0, 0);
58         printf ("\n");
59     }
60     return 0;
61 }
View Code

 

posted on 2013-08-16 15:59  圣手摘星  阅读(297)  评论(0编辑  收藏  举报

导航