2020.10.17 天梯赛练习 补题报告

7-9 小字辈

 1.题意

  给定家族人口总数 N,家族成员从 1 到 N 编号,第二行给出 N 个编号,其中第 i 个编号对应第 i 位成员的父/母,家谱中辈分最高的老祖宗对应的父/母编号为 -1。输出最小的辈分(老祖宗的辈分为 1,以下逐级递增),然后在第二行按递增顺序输出辈分最小的成员的编号。

 2.题解

  用vector数组存根与它的孩子,设祖宗的辈分是1,辈分越小辈分++,dfs更新最小辈分,搜到最小辈,塞进一个vector里。

 3.代码

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int inf = 0x3f3f3f3f;
 5 const int maxn = 1e5 + 5;
 6 vector<int> descents[maxn], v;
 7 int n, a, ancestor;
 8 int maxdp = -1;
 9 void dfs(int root, int dep) {
10     if(dep == maxdp) {
11         v.push_back(root);
12     }  
13     
14     if(dep > maxdp) {  
15         maxdp = dep;
16         v.clear();
17         v.push_back(root);
18     }
19     
20     for(int i = 0; i<(int)descents[root].size(); i++) {
21         dfs(descents[root][i], dep + 1);
22     }
23 }
24 int main() {
25     scanf("%d", &n);
26     for(int i = 1; i <= n; i++) {
27         scanf("%d", &a);
28         if(a == -1) {
29             ancestor = i;
30             continue;
31         }
32         descents[a].push_back(i);
33     }
34     
35     dfs(ancestor, 1);
36     sort(v.begin(), v.end());
37     printf("%d
", maxdp);
38     
39     for(int i = 0; i < (int)v.size(); i++) {
40         if(i != 0)
41             printf(" ");
42         printf("%d", v[i]);
43     }
44     
45     return 0;
46 }
View Code

7-11 互评成绩

 1.题意

  给定3个正整数,学生总数N、每份作业的评审数k、需要输出的学生数M,随后N行,每行给出一份作业得到的k个评审成绩,其间以空格分隔。每个人的作业会被k个同学评审,得到k个成绩。系统需要去掉一个最高分和一个最低分,将剩下的分数取平均,就得到这个学生的最后成绩。按非递减顺序输出最后得分最高的M个成绩,保留小数点后3位。

 2.题解

  模拟,把成绩塞到vector里即可,当时用的不熟,导致部分正确。

 3.代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 const int maxn = 1e5 + 5;
 5 vector<double> v, ans;
 6 bool cmp(double a, double b) {
 7     return a > b;
 8 }
 9 int main() {
10     int n, k, m;
11     scanf("%d%d%d", &n, &k, &m);
12     
13     for(int i = 1; i <= n; i++) {
14         double a[k + 1] = {0.0};
15         for(int j = 1; j <= k; j++) {
16             scanf("%lf", &a[j]);
17         }
18         sort(a + 1, a + 1 + k);
19         double sum = 0.0;
20         for(int j = 2; j < k; j++) {
21             sum += a[j];
22         }
23         double ans = sum / (double)(k - 2); 
24         v.push_back(ans);
25     }
26     
27     sort(v.begin(), v.end());
28     int cnt = 0;
29     for(int i = (int)v.size() - 1; i >= 0; cnt++, i--) {
30         if(cnt == m) {
31             break;
32         }
33         ans.push_back(v[i]);
34     }
35     
36     for(int i = (int)ans.size() - 1; i >= 0; i--) {
37         if(i == 0) {
38             printf("%.3f", ans[i]);
39         } else {
40             printf("%.3f ", ans[i]);
41         }        
42     }
43     
44     return 0;
45 }
View Code

7-12 深入虎穴

 1.题意

  情报藏在一个地下迷宫里,迷宫只有一个入口,里面有很多条通路,每条路通向一扇门。每一扇门背后或者是一个房间,或者又有很多条路,同样是每条路通向一扇门,不存在两条路通向同一扇门,找出距离入口最远的那扇门。给定门的数量N,最后 N 行,第 i 行描述编号为 i 的那扇门背后能通向的门。在一行中输出距离入口最远的那扇门的编号。

 2.题解

  题目没给入口,需要把入口找到,没有哪扇门会通向入口,所以用vis数组记录每个门是否被通向,没被通向的那扇门就是入口,再用bfs搜到最深点。

 3.代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 const int maxn = 1e5 + 5;
 5 int n;
 6 vector<int> v[maxn];
 7 bool inq[maxn];
 8 bool vis[maxn];
 9 int level[maxn];
10 int deepest;
11 int deepest_vertex;
12 void bfs(int s) {
13     queue<int> q;
14     q.push(s);    
15     inq[s] = true;
16     level[s] = 1;
17     while(!q.empty()) {
18         int fro = q.front();
19         q.pop();
20         if(level[fro] > deepest) {
21             deepest = level[fro];
22             deepest_vertex = fro;
23         }
24             
25         for(int i = 0; i < v[fro].size(); i++) {
26             int u = v[fro][i];
27             if(!inq[u]) {
28                 level[u] = level[fro] + 1;
29                 q.push(u);
30                 inq[u] = true;
31             }
32         }
33     }
34 }
35 int main() {
36     scanf("%d", &n);
37     int k, x;
38     for(int i = 1; i <= n; i++) {
39         scanf("%d", &k);
40         for(int j = 0; j < k; j++) {
41             scanf("%d", &x);
42             vis[x] = true;
43             v[i].push_back(x);
44         }
45     }
46     for (int i = 1; i <= n; i++) {
47         if (!vis[i]) {
48             bfs(i);
49         }
50     }
51     cout << deepest_vertex;
52     
53     return 0;
54 }
View Code
原文地址:https://www.cnblogs.com/lvguapi/p/13834699.html