zoukankan      html  css  js  c++  java
  • 刘汝佳 算法竞赛-入门经典 第二部分 算法篇 第六章 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
    ");
    78         else printf ("no
    ");
    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 ("
    ");
    104         print (root2);
    105         printf ("
    ");
    106 */
    107         DFS(root1, root2, 0);
    108         printf ("There are %d black pixels.
    ", 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:
    ", 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 ("
    
    ");
    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:
    ", cas ++);
    74         for (int i = Min+1; i < Max; i ++)
    75             printf ("%d%c", stor[i], (i == Max-1) ? '
    ' : ' ');
    76         printf ("
    ");
    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
    ", ope);
    104         ans = solve();
    105         
    106         printf ("    value = %d
    ", ans);
    107         for (int i = 'a'; i <= 'z'; i ++)
    108             if (appear[i])
    109             printf ("    %c = %d
    ", 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
    ");
    36         else printf ("NO
    ");
    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 ("
    ");
    59     }
    60     return 0;
    61 }
    View Code
  • 相关阅读:
    二十九:CSRF及SSRF漏洞案例讲解
    二十八:XSS跨站之WAF绕过及安全检测
    二十七:XSS跨站之代码及httponly绕过
    二十六:XSS跨站之订单及shell箱子反杀
    二十五:XSS跨站值原理分类及攻击手法
    二十四:文件上传之WAF绕过及安全修复
    二十三:文件上传之解析漏洞编辑器安全
    二十二:内容逻辑数组绕过
    mysql-----04 多表查询
    Python·——进程1
  • 原文地址:https://www.cnblogs.com/shengshouzhaixing/p/3262340.html
Copyright © 2011-2022 走看看