刘汝佳 算法竞赛-入门经典 第二部分 算法篇 第六章 2(Binary Trees)
112 - Tree Summing
题目大意:给出一个数,再给一颗树,每个头节点的子树被包含在头节点之后的括号里,寻找是否有从头节点到叶子的和与给出的数相等,如果有则输出yes,没有输出no!
解题思路:按照括号匹配的原则,调用栈,求从头节点到叶子节点的和!
解题代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
548 - Tree
题目大意:给出一颗二叉树的中序遍历和后序遍历,求从头节点到叶子节点的最小和,并且将获得该最小和的路径的叶子节点的值输出。
解题思路:根据中序遍历和后序遍历递归建树,找到最小和,并保存该路径的叶子节点的值!
解题代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
297 - Quadtrees
解题思路:递归建树,寻找黑节点,找到后将该节点所占像素累加起来,最后输出!
解题代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
712 - S-Trees
此题Submission error先把代码放这。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
699 - The Falling Leaves
题目大意:给一颗树的先序遍历,-1代表空节点,那么给出的便是满二叉树,求从左到右竖直在一条直线的节点的和,并从左到有输出。子节点与父节点水平距离为1。
解题思路:先把树存入,后按照节点位置累加和,运用map容器可运用负数作下标,怎很容易保存节点位置。
解题代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
327 - Evaluating Simple C Expressions
题目意思很显然。
解题思路:直接模拟各种运算符结合的情况。
解题代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
839 - Not so Mobile
题目大意:给出一个杠杆,w1,d1,w2,d2,判断杠杆是否平衡,即w1*d1 == w2*d2;如果w1 为 0则说明,左边杠杆下还有杠杆,w2为0亦然。判断所有杠杆是否平衡。
解题思路:按照输入直接递归判断。
解题代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
10562 - Undraw the Trees
题意也很显然。
解题代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }