Loading

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。

posted @ 2021-04-18 21:50  山寨功夫侠  阅读(43)  评论(0)    收藏  举报