题干:1151 LCA in a Binary Tree (30 分)
题解:我这道题得分14分,第1个和第3个测试点错误,这题我花的时间远超考试要求的时间,因为我后面还去学习了LCA的概念和算法,并且整合到这道题目中,总共花了应该有4个小时左右。总的来说收获还是很大的,对二叉树的几种表示结构有更深的认识,还有深度遍历在解题中的具体应用,包括加深了对于几种遍历方式建树的认识。。。。。
- 其实说心里话,我觉得就按照大学一般的数据结构与算法课程下去,有的学校可能只有上理论课,然后补充一点编程实验,其实这样的强度,对于学生熟练掌握这些知识并用于实际问题的要求是远远不够的,它需要专门的做相关的编程题,并不仅仅是那些理论选择题,比如问你怎样判断完全二叉树。。。然后让你写下来,一定要在编程中感受和体会
- 当然不是让学生自己绞尽脑汁去想这些经典算法的问题,我们的要点不是要用题目难倒学生,而是通过题目来引导学生学生去体会这些基本的算法,结构和理论性质,只有从实践中来的知识,学生才会有更深的印象,也才能在实践中信手拈来。
- 这段代码非常适合希望专题去做树相关编程训练的同学,其实在这个阶段的同学,相信你和我一样都听说过“模板代码”这个概念,其实吧,所谓的模板并不是用来一遍遍的抄写然后记下来的,而且很多人,并且包括我自己,觉得学习算法,是一个记忆的过程,其实不然,因为如果你单单去记忆它,其实很容易就忘掉了,关键还是在于刷题的过程中去应用它,去体会它,可能你一次不会想起来,也许第二次还不行,一般第三次做类似的题目的时候,你会一点点的上手了。所以一时记不下来不要担心,多做题,多去体会题目就熟悉了。
- 最后,我继续强烈推荐你们学习使用visual studio的进行PAT的训练,也许线下考试用不了,但我也强烈建议你选择使用vs,因为在学习的阶段,vs强大的调试功能,能够非常的方便你去定位出问题的代码是在那里,自动变量的机制会让你一用就彻底爱上它。。。特别是在代码出错,而你十分紧张的时候,自动变量能够非常智能的减少你在调试的时候需要遇到的大量繁琐工作。。。特别是在做这种代码量大的30分题的时候,而且如果你有使用别人的代码,断点进去然后单步一点点运行,对于理解他人的代码作用也是非常方便的。。。。而且vs还有一个非常重要的功能,就是在数组或者vector越界访问的时候,会直接弹出一个异常,像Dev和code block这样的轻型IDE只会卡在那里。。。。如果你自己写题解,那么越界访问应该可以是高频错误里面的高频错误了,所以用vs吧,当你熟练以后,你可以考虑放弃visual studio用其他的IDE
- 最后的最后,也是我最深的感受,冲刺阶段心态不崩是最最重要的,其实对每个人来说,都是拼劲全力去生活,哪怕我曾经逃避过高三一样,对我而言,我是个追求极致和完美的人,我当时的经历和阅历让我无法承担这样的压力,也许对于其他的人来说,他们面对的压力还在可以接受的范围吧。。。。今天我有了一定的阅历,但我仍然会感到一定的恐惧和担心,但我不能逃避,我要一天天的坚持下去,继续拼劲全力去学习去生活。面对生活中你感到有压力和棘手的事情,逃避不是办法,解决的唯一方法就是面对它,想尽一切可能办法去解决它,这才是克服压力和恐惧的最最根本的办法。。。。但是生活里时间是有限的。。。你可能需要根据自己的需要去挑重点
- 题解:
// A1151.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <bits/stdc++.h> using namespace std; #define max 10010 int m, n; struct node { int val;//int index;index parent;int data node* left; node* right; node() { val = 0; left = right = NULL; } }; vector<int> pre; vector<int> in; vector<int> parent(max); node* build(int root,int start,int end) { if(start>end){ return NULL; } int i = start; for (; i < end; i++) { if (in[i] == pre[root]) { break; } } node* t = new node(); t->left = build(root + 1, start, i - 1); t->right = build(root + 1 + i - start, i + 1, end); t->val = pre[root]; return t; } void find_parent(node* root) {//implement via modify DFS //cout << root->val << " "; if (root->left != NULL) { parent[root->left->val]=root->val; find_parent(root->left); } if (root->right != NULL) { parent[root->right->val] = root->val; find_parent(root->right); } } int lca(int x, int y,node* root) { vector<bool> visited(n+1,false); while (x != root->val) { visited[x] = true; x = parent[x]; } visited[x] = true; while (visited[y] == false&&y<=n) { y = parent[y]; } return y; } int main() { #ifndef ONLINE_JUDGE #pragma warning(disable:4996) freopen("in.txt", "r", stdin); #endif // !ONLINE_JUDGE cin >> m >> n; pre.resize(n); in.resize(n); for (int i = 0; i < n; i++) { cin >> in[i]; } for (int i = 0; i < n; i++) { cin >> pre[i]; } node* root = NULL; root = build(0,0,n-1); find_parent(root); //cout << endl; int x, y,z; for (int i = 0; i < m; i++) { cin >> x >> y; if ((y <= n && y >= 1)&& (x <= n && x >= 1) ) { z = lca(x, y, root); if (z != x && z != y) { printf("LCA of %d and %d is %d.\n", x, y, z); } if (z == x && z != y) { printf("%d is an ancestor of %d.\n", x, y); } if (z != x && z == y) { printf("%d is an ancestor of %d.\n", y, x); } if (z == x && z == y) { printf("%d is an ancestor of %d.\n", x, y); } } else if ((y<1 || y>n) && (x<1 || x>n)) { printf("ERROR: %d and %d are not found.\n",x,y); } else if (y<1 || y>n) { printf("ERROR: %d is not found.\n", y); } else if (x<1 || x>n) { printf("ERROR: %d is not found.\n", x); } //cout << lca(x, y, root) << endl; } return 0; } void level_order(node* root) { queue<node*> q; if (root != NULL) { q.push(root); } while (q.empty() == false) { cout << q.front()->val << " "; if (q.front()->left != NULL) { q.push(q.front()->left); } if (q.front()->right != NULL) { q.push(q.front()->right); } q.pop(); } }
别人的满分代码
-
#include <iostream> #include <vector> #include <map> using namespace std; map<int, int> pos; vector<int> in, pre; void lca(int inl, int inr, int preRoot, int a, int b) { if (inl > inr) return; int inRoot = pos[pre[preRoot]], aIn = pos[a], bIn = pos[b]; if (aIn < inRoot && bIn < inRoot) lca(inl, inRoot-1, preRoot+1, a, b); else if ((aIn < inRoot && bIn > inRoot) || (aIn > inRoot && bIn < inRoot)) printf("LCA of %d and %d is %d.\n", a, b, in[inRoot]); else if (aIn > inRoot && bIn > inRoot) lca(inRoot+1, inr, preRoot+1+(inRoot-inl), a, b); else if (aIn == inRoot) printf("%d is an ancestor of %d.\n", a, b); else if (bIn == inRoot) printf("%d is an ancestor of %d.\n", b, a); } int main() { int m, n, a, b; scanf("%d %d", &m, &n); in.resize(n + 1), pre.resize(n + 1); for (int i = 1; i <= n; i++) { scanf("%d", &in[i]); pos[in[i]] = i; } for (int i = 1; i <= n; i++) scanf("%d", &pre[i]); for (int i = 0; i < m; i++) { scanf("%d %d", &a, &b); if (pos[a] == 0 && pos[b] == 0) printf("ERROR: %d and %d are not found.\n", a, b); else if (pos[a] == 0 || pos[b] == 0) printf("ERROR: %d is not found.\n", pos[a] == 0 ? a : b); else lca(1, n, 1, a, b); } return 0; }