• 华为 2022_09_07 笔试题复盘


    T1

    题目描述

    老李在多年前承包了一个养猪场,并引入了若干只种猪,经过这些年的经营,现在养猪场有 N 只猪,编号从 0 到 N - 1(每只猪无论生死都有唯一的编号);

    老李在每只猪生产的时候记下了生产的母猪和出生的小猪,格式:x y1 y2 y3 ...(注:x 为猪妈妈,y1,y2,y3 ... 为新生的猪仔,以上编码均在 0,...,N - 1内,每只猪可以多次生产,每个猪崽只有一个猪妈妈);

    为了防疫需要,要检查任意两只猪是否有亲戚关系(两只猪具有相同的祖先),并计算关系亲疏情况(关系距离,相同编号距离为 0)

    输入:第一行输入总数 N

    第二行表示后续生产记录行数 M

    后续 M 行输入生产记录,以空格分隔

    最后一行输入m1,m2;表示待检查的m1和m2编号

    输出

    一个整数,表示m1,和m2之间的关系距离,无亲戚关系输出 -1

    思路

    先根据输入 使用 unordered_map 记录每只小猪的猪妈妈是谁,并且找的树的根,将其妈妈编码设定为 -1,作为循环终止条件。

    从 m1 开始遍历 m1 的所有祖先,若有 m2,输出当前距离,直接 return 掉;若不是 m2,则使用 unordered_map 把当前祖先到 m1 的距离记下来。

    若没结束,再从 m2 开始遍历 m2 的所有祖先,若出现 m1 的祖先,直接将两个距离相加输出,结束。

    如果此时还没结束,说明 m1 和 m2 没有公共祖先,则输出 -1,结束;

    代码

    1. #include
    2. #include
    3. using namespace std;
    4. int main() {
    5. int N, M;
    6. cin >> N >> M;
    7. unordered_map<int, int> pigs_mum;
    8. while (M--) {
    9. int pig_mum, pig_son;
    10. cin >> pig_mum;
    11. while (cin >> pig_son) {
    12. pigs_mum[pig_son] = pig_mum;
    13. if (cin.get() == '\n') break;
    14. }
    15. }
    16. for (int i = 0; i < N; ++i) {
    17. if (pigs_mum.find(i) == pigs_mum.end()) {
    18. pigs_mum[i] = -1;
    19. }
    20. }
    21. int m1, m2;
    22. cin >> m1 >> m2;
    23. unordered_map<int, int> distance;
    24. int tmp = m1, d = 0;
    25. while (tmp != -1) {
    26. if (tmp == m2) {
    27. cout << d << endl;
    28. return 0;
    29. }
    30. else {
    31. distance[tmp] = d;
    32. d++;
    33. tmp = pigs_mum[tmp];
    34. }
    35. }
    36. tmp = m2; d = 0;
    37. while (tmp != -1) {
    38. if (distance.find(tmp) != distance.end()) {
    39. cout << (d + distance[tmp]) << endl;
    40. return 0;
    41. }
    42. else {
    43. d++;
    44. tmp = pigs_mum[tmp];
    45. }
    46. }
    47. cout << -1 << endl;
    48. return 0;
    49. }

    T2

    题目描述:

    在一个 M * N 的街区种,有一个士兵 S 和一个敌人 E,表示 X 为无法通过的街区,标识 B 为可以通过的街区;士兵在一个单位时间内可以从一个街区移动到相邻的街区(士兵每次只能水平或者垂直方向移动一个街区);士兵每次改变方向时,需要额外花费一个单位的时间(士兵第一次移动一个街区时,不用考虑其初始方向,即只需要一个单位时间即可到达相邻街区)。计算士兵 S 最少 需要多少时间才能到达 E 所在的街区。

    输入:第一行两个数组,表示街区大小,M行,N列;

    接下来M行,每行N个字母,字母 S 表示士兵所在街区,字母 E 表示敌人所在街区,字母 X 表示障碍,字母 B 表示可以经过的街区。(只有一个 S,一个 E);

    输出:最少需要的时间,当士兵 S 永远无法到达敌人 E 所在的街区时,输出 -1;

    思路

    经典 dfs 题,笔试的时候脑袋抽筋了,搜到终点的时候,忘记 return 了,哎,难受!

    代码

    1. #include
    2. #include
    3. using namespace std;
    4. static int res = INT32_MAX;
    5. void dfs(vectorchar>>& map, int i, int j, int step, int dir) {
    6. if (i < 0 || i >= map.size() || j < 0 || j >= map[0].size()) return;
    7. if (map[i][j] == 'X' || map[i][j] == 'S') return;
    8. if (map[i][j] == 'E') {
    9. res = min(res, step);
    10. return;
    11. }
    12. map[i][j] = 'X';
    13. int step_plus[4];
    14. step_plus[0] = (dir == 0 ? 1 : 2);
    15. step_plus[1] = (dir == 1 ? 1 : 2);
    16. step_plus[2] = (dir == 2 ? 1 : 2);
    17. step_plus[3] = (dir == 3 ? 1 : 2);
    18. dfs(map, i - 1, j, step + step_plus[0], 0);
    19. dfs(map, i, j + 1, step + step_plus[1], 1);
    20. dfs(map, i + 1, j, step + step_plus[2], 2);
    21. dfs(map, i, j - 1, step + step_plus[3], 3);
    22. map[i][j] = 'B';
    23. }
    24. int main() {
    25. int m, n;
    26. cin >> m >> n;
    27. int start_x, start_y;
    28. vectorchar>> map(m, vector<char>(n));
    29. for (int i = 0; i < m; ++i) {
    30. string s;
    31. cin >> s;
    32. for (int j = 0; j < n; ++j) {
    33. map[i][j] = s[j];
    34. if (s[j] == 'S') {
    35. start_x = i;
    36. start_y = j;
    37. }
    38. }
    39. }
    40. dfs(map, start_x - 1, start_y, 1, 0);
    41. dfs(map, start_x, start_y + 1, 1, 1);
    42. dfs(map, start_x + 1, start_y, 1, 2);
    43. dfs(map, start_x, start_y - 1, 1, 3);
    44. if (res == INT32_MAX) cout << -1 << endl;
    45. else cout << res << endl;
    46. return 0;
    47. }

    T3

    题目描述:

    某公司停车场安装了一套智慧停车系统,在车辆进入停车场时,系统会自动计算一条最短路径,并为这一条路径在地面点亮导路灯,如果没有可用停车位,则在入口亮起红灯。

    为了简化处理,我们使用起始的车道坐标表示停车场入口,用一个二维数组来记录当前的停车情况,如:

    1. 8 15 8 1
    2. 1 2 2 1 2 2 1 2 2 1 2 2 1 2 1
    3. 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    4. 1 2 1 2 1 0 1 3 2 2 2 1 2 2 2
    5. 1 2 1 2 2 0 1 3 1 2 1 2 1 2 1
    6. 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    7. 2 1 2 2 2 0 2 2 1 1 0 1 2 1 2
    8. 2 2 2 2 2 0 2 2 2 2 0 2 2 2 2
    9. 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    • 8 15 表示矩阵的行数 M 值 8,和列数 N 值 15;
    • 8 1 表示入口坐标(分别表示行和列,行列号均从1号计数):8 代表第 8 行,1 代表第 1 列,以空格分割;即表示入口时绿地从这个坐标点开始点亮;
    • 矩阵数代表停车场情况,0 代表车道;1 代表空车位;2 代表已停车车位;3 代表柱子,不可通过;

    请你根据停车场情况,点亮一条通往可用车位的最短路径。

    路径规则:

    1. 所有车位为南北向,车辆只能从车位的南侧或北侧的车道进入停车位,不能横向停车;
    2. 如果存在相同距离的目标车位,优先选择行坐标比较小的,其次选择列坐标比较小的;
    3. 如果到达同一个车位有多条相同距离的路径,有限选择路径节点行坐标和较小的,其次选择列坐标和较小的;

    输入:

    M N i j

    A11 ... A1j ... A1N

    ...

    Ai1 ... Aij  ...  Ain

    ...

    Am1 ... Amj ... Amn

    输出:

    输出导路灯的路径坐标

    如果没有可用的停车位,则输出:-1 -1

    如果存在可用的停车位,则输出最短路径(依次输出的每两个数代表一个点)

    思路

    这就是一个 bfs 搜寻路径的题目,只是需要考虑的点较多;起点是给定的,终点未知,要在搜寻的过程中判断;

    题目需要输出路径,所有需要维护一个二维 path 数组来记录路径,记录方式为将 path[i][j] 的值赋为 1, 2, 3, 4,分别表示当前点是从哪个方向搜过来的;

    另外需要考虑路径距离相同的情况,题目给定有限考虑行标较小,或行和较小;

    所以在 bfs 搜索每个节点的四个方向时,优先 上,在左,然后下,最后右,按照这个顺序去入队列,应该是可以保证最优的(笔试时细节没做好,没有运行出来,所以不确定)

    代码

    仅代表个人想法,不确定是不是能 accept,题目所给测试案例都能通过;

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. static int dir_x[] = {-1, 0, 1, 0};
    6. static int dir_y[] = {0, -1, 0, 1};
    7. int main() {
    8. int m, n, begin_x, begin_y;
    9. cin >> m >> n >> begin_x >> begin_y;
    10. vectorint>> parking(m, vector<int>(n));
    11. for (int i = 0; i < m; ++i) {
    12. for (int j = 0; j < n; ++j) {
    13. cin >> parking[i][j];
    14. }
    15. }
    16. begin_x--;
    17. begin_y--;
    18. vectorint>> path(m, vector<int>(n, 0));
    19. queueint>> que;
    20. que.push({begin_x, begin_y});
    21. parking[begin_x][begin_y] = 3;
    22. vector<int> end = {-1, -1};
    23. while (!que.empty()) {
    24. bool flag = false;
    25. int size = que.size();
    26. for (int i = 0; i < size; ++i) {
    27. vector<int> loc = que.front();
    28. que.pop();
    29. for (int i = 0; i < 4; ++i) {
    30. int next_x = loc[0] + dir_x[i], next_y = loc[1] + dir_y[i];
    31. if (next_x < 0 || next_x >= m || next_y < 0 || next_y >= n) continue;
    32. if ((i == 0 || i == 2) && parking[next_x][next_y] == 1) {
    33. end = {next_x, next_y};
    34. path[next_x][next_y] = i + 1;
    35. flag = true;
    36. break;
    37. }
    38. else if (parking[next_x][next_y] == 0) {
    39. que.push({next_x, next_y});
    40. parking[next_x][next_y] = 3;
    41. path[next_x][next_y] = i + 1;
    42. }
    43. }
    44. }
    45. if (flag) break;
    46. }
    47. if (end[0] == -1 && end[1] == -1) {
    48. cout << -1 << " " << -1 << endl;
    49. }
    50. else {
    51. vector<int> outPath;
    52. int x = end[0], y = end[1];
    53. while (x != begin_x || y != begin_y) {
    54. outPath.push_back(y);
    55. outPath.push_back(x);
    56. if (path[x][y] == 1) x--;
    57. if (path[x][y] == 2) y++;
    58. if (path[x][y] == 3) x++;
    59. if (path[x][y] == 4) y--;
    60. }
    61. outPath.push_back(begin_y);
    62. outPath.push_back(begin_x);
    63. for (int i = outPath.size() - 1; i > 0; --i) {
    64. cout << outPath[i] + 1 << " ";
    65. }
    66. cout << outPath[0] + 1 << endl;
    67. }
    68. return 0;
    69. }

  • 相关阅读:
    PMP每日一练 | 考试不迷路-11.09(包含敏捷+多选)
    2022腾讯全球数字生态大会【存储专场】它来了|预约有礼
    属性和字段的区别
    高危安全漏洞风险提示:Oracle7月修复Weblogic Server严重RCE漏洞
    Java知识梳理第一章 Java概况
    java项目基于 SSM+JSP 的毕业生就业信息管理系统,保证可用
    UE5之5.4 第一人称示例代码阅读2 子弹发射逻辑
    vue3 axios
    屏幕录制视频编辑软件 Camtasia 2023 mac中文版软件功能
    微信支付 APP端 第三弹 申请退款
  • 原文地址:https://blog.csdn.net/Yetao1996/article/details/126759374