PAT 1004 Counting Leaves
问题:对于一个家谱树,你的任务是统计没有子女的家族成员的个数。原问题链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805521431773184
解决方案:
生成邻接矩阵,利用DFS或者BFS遍历每个节点,在遍历过程中,更新每个节点的深度,并统计不同深度的节点的个数,存放在book数组中。
代码:
1 #include<iostream> 2 #include<vector> 3 4 using namespace std; 5 6 vector<int> v[100]; //邻接矩阵 7 int book[100] = { 0 }; //存放不同深度节点个数的矩阵 8 int maxDepth = -1; 9 10 void dsp(int index, int depth) { //在DFS遍历过程中更新depth并统计不同深度的节点的个数 11 if (v[index].size() == 0) { 12 book[depth]++; 13 if (maxDepth < depth) 14 maxDepth = depth; 15 return; 16 } 17 for (int i = 0; i < v[index].size(); i++) { 18 dsp(v[index][i], depth + 1); 19 } 20 } 21 22 int main() { 23 int number, N, M, index, temp; 24 cin >> N >> M; 25 for (int i = 0; i < M; i++) { //构造邻接矩阵 26 cin >> index >> number; 27 for (int j = 0; j < number; j++) { 28 cin >> temp; 29 v[index].push_back(temp); 30 } 31 } 32 dsp(1, 0); 33 cout << book[0]; 34 for (int i = 1; i <= maxDepth; i++) 35 cout << " " << book[i]; 36 return 0; 37 }
上面的代码清晰,易理解,测试点也都能通过。不过我最开始不是这么写的,我之前的写法比较low。我是写一个class类(太麻烦了。。。),而且DFS递归过程中对于depth的更新也显得比较呆。。。具体就是下面的代码(还有两个测试点不能通过,也不知道是为啥。。。)
1 #include<iostream> 2 #include<algorithm> 3 #include<queue> 4 5 using namespace std; 6 7 class Node { 8 private: 9 int number; 10 int position; 11 int* child; 12 int depth; 13 public: 14 Node() { 15 this->number = 0; 16 this->position = 0; 17 this->child = NULL; 18 this->depth = 0; 19 } 20 void setNode(int number) { 21 this->number = number; 22 this->child = new int[this->number]{ 0 }; 23 } 24 int isChild() { 25 return this->child == NULL ? 0 : 1; 26 } 27 void setChild(int num) { 28 this->child[this->position] = num; 29 this->position++; 30 } 31 void setDepth(int depth) { 32 this->depth = depth; 33 } 34 int getDepth() { 35 return this->depth; 36 } 37 int getNumber() { 38 return this->number; 39 } 40 int getSub(int i) { 41 return this->child[i]; 42 } 43 ~Node() { delete[] this->child; }; 44 }; 45 46 int main() { 47 int number, N, M, index, temp, p, maxdepth; 48 int book[100] = { 0 }; 49 std::queue<int> q; 50 cin >> N >> M; 51 class Node* Array = new Node[N + 1]; 52 for (int i = 0; i < M; i++) { 53 cin >> index >> number; 54 Array[index].setNode(number); 55 for (int j = 0; j < number; j++) { 56 cin >> temp; 57 Array[index].setChild(temp); 58 Array[temp].setDepth(Array[index].getDepth() + 1); 59 } 60 } 61 maxdepth = 0; 62 q.push(1); 63 while (!q.empty()) { 64 p = q.front(); 65 q.pop(); 66 if (!Array[p].isChild()) { 67 book[Array[p].getDepth()]++; 68 if (maxdepth < Array[p].getDepth()) 69 maxdepth = Array[p].getDepth(); 70 } 71 for (int i = 0; i < Array[p].getNumber(); i++) { 72 q.push(Array[p].getSub(i)); 73 } 74 } 75 for (int i = 0; i < maxdepth; i++) 76 cout << book[i] << " "; 77 cout << book[maxdepth]; 78 return 0; 79 }
现在,我大概明白了为啥还有两个测试点不能通过,是因为第二个代码在更新depth的时候是在上面节点的基础上加一,看似很合理,但实际上在输入过程中,如果子节点在父节点之前输入就会出错,比如先输入节点02,再输入节点01,这样01和02的深度便都是0(在输入02后不会在01的基础上加一,而且输入01后不会更新02的深度),但是实际上01的深度为0,而02的深度为1。

浙公网安备 33010602011771号