机考E卷100分题 - We Are A Team

题目描述

总共有 n 个人在机房,每个人有一个标号(1<=标号<=n),他们分成了多个团队,需要你根据收到的 m 条消息判定指定的两个人是否在一个团队中,具体的:

  1. 消息构成为 a b c,整数 a、b 分别代表两个人的标号,整数 c 代表指令
  2. c == 0 代表 a 和 b 在一个团队内
  3. c == 1 代表需要判定 a 和 b 的关系,如果 a 和 b 是一个团队,输出一行’we are a team’,如果不是,输出一行’we are not a team’
  4. c 为其他值,或当前行 a 或 b 超出 1~n 的范围,输出‘da pian zi’

输入描述

  1. 第一行包含两个整数 n,m(1<=n,m<100000),分别表示有 n 个人和 m 条消息
  2. 随后的 m 行,每行一条消息,消息格式为:a b c(1<=a,b<=n,0<=c<=1)

输出描述

  1. c ==1,根据 a 和 b 是否在一个团队中输出一行字符串,在一个团队中输出‘we are a team‘,不在一个团队中输出’we are not a team’
  2. c 为其他值,或当前行 a 或 b 的标号小于 1 或者大于 n 时,输出字符串‘da pian zi‘
  3. 如果第一行 n 和 m 的值超出约定的范围时,输出字符串”Null“。

示例1

输入

1 2 0
4 5 0
2 3 0
1 2 1
2 3 1
4 5 1
1 5 1

输出

We are a team
We are a team
We are a team
We are not a team

说明

示例2

输入

5 6
1 2 0
1 2 1
1 5 0
2 3 1
2 5 1
1 3 2

输出

we are a team
we are not a team
we are a team
da pian zi

说明

解题思路

题目要求判断给定的两个人是否在同一个团队中。、

输入包含 n 个人和 m 条消息。

每条消息包含 a、b 和 c,其中 a 和 b 是两个人的标号,c 是指令。

  • c == 0 表示 a 和 b 在同一个团队
  • c == 1 表示需要判断 a 和 b 是否在同一个团队。

示例解释:

输入:

5 7
1 2 0
4 5 0
2 3 0
1 2 1
2 3 1
4 5 1
1 5 1
  1. 前三条消息表示:
    • 1 和 2 在同一个团队
    • 4 和 5 在同一个团队
    • 2 和 3 在同一个团队
  2. 因此,团队关系如下:
    • 团队1:1, 2, 3
    • 团队2:4, 5
  3. 接下来的四条消息要求判断两个人是否在同一个团队:
    • 1 和 2:在同一个团队(团队1),输出 “We are a team”
    • 2 和 3:在同一个团队(团队1),输出 “We are a team”
    • 4 和 5:在同一个团队(团队2),输出 “We are a team”
    • 1 和 5:不在同一个团队,输出 “We are not a team”

Java

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        // 读取输入,获取人数和消息数量
        Scanner sc = new Scanner(System.in);
        int numPeople = sc.nextInt();
        int numMessages = sc.nextInt();

        // 读取消息并存储到二维数组中
        int[][] messages = new int[numMessages][3];
        for (int i = 0; i < numMessages; i++) {
            messages[i][0] = sc.nextInt();
            messages[i][1] = sc.nextInt();
            messages[i][2] = sc.nextInt();
        }

        // 检查输入范围,如果超出范围则输出 "Null"
        if (numPeople < 1 || numPeople >= 100000 || numMessages < 1 || numMessages >= 100000) {
            System.out.println("Null");
            return;
        }

        // 初始化数组,用于存储每个人的团队信息
        int[] parent = new int[numPeople + 1];
        for (int i = 0; i < numPeople + 1; i++) parent[i] = i;

        // 遍历消息,根据指令处理团队关系
        for (int[] message : messages) {
            int personA = message[0], personB = message[1], command = message[2];

            // 检查输入范围,如果超出范围则输出 "da pian zi"
            if (personA < 1 || personA > numPeople || personB < 1 || personB > numPeople) {
                System.out.println("da pian zi");
                continue;
            }

            // 如果指令为 0,则合并 personA 和 personB 所在的团队
            if (command == 0) {
                int rootA = find(personA, parent);
                int rootB = find(personB, parent);

                if (rootA != rootB) {
                    parent[rootB] = rootA;
                }
            }
            // 如果指令为 1,则判断 personA 和 personB 是否在同一个团队
            else if (command == 1) {
                System.out.println(find(personA, parent) == find(personB, parent) ? "We are a team" : "We are not a team");
            }
            // 如果指令为其他值,则输出 "da pian zi"
            else {
                System.out.println("da pian zi");
            }
        }
    }

    // 查找节点,用于判断两个人是否在同一个团队
    public static int find(int x, int[] parent) {
        if (parent[x] != x) {
            return parent[x] = find(parent[x], parent);
        }
        return x;
    }
}

Python

def find(x, parent):
    # 查找节点,用于判断两个人是否在同一个团队
    if parent[x] != x:
        parent[x] = find(parent[x], parent)
    return parent[x]


# 读取输入,获取人数和消息数量
num_people, num_messages = map(int, input().split())

# 读取消息并存储到二维数组中
messages = [list(map(int, input().split())) for _ in range(num_messages)]

# 检查输入范围,如果超出范围则输出 "Null"
if num_people < 1 or num_people >= 100000 or num_messages < 1 or num_messages >= 100000:
    print("Null")
else:
    # 初始化数组,用于存储每个人的团队信息
    parent = list(range(num_people + 1))

    # 遍历消息,根据指令处理团队关系
    for message in messages:
        person_a, person_b, command = message

        # 检查输入范围,如果超出范围则输出 "da pian zi"
        if person_a < 1 or person_a > num_people or person_b < 1 or person_b > num_people:
            print("da pian zi")
            continue

        # 如果指令为 0,则合并 person_a 和 person_b 所在的团队
        if command == 0:
            root_a = find(person_a, parent)
            root_b = find(person_b, parent)

            if root_a != root_b:
                parent[root_b] = root_a
        # 如果指令为 1,则判断 person_a 和 person_b 是否在同一个团队
        elif command == 1:
            print("We are a team" if find(person_a, parent) == find(person_b, parent) else "We are not a team")
        # 如果指令为其他值,则输出 "da pian zi"
        else:
            print("da pian zi")

JavaScript

const readline = require('readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

// 查找节点,用于判断两个人是否在同一个团队
function find(x, parent) {
  if (parent[x] !== x) {
    parent[x] = find(parent[x], parent);
  }
  return parent[x];
}

let inputLines = [];
rl.on('line', (input) => {
  inputLines.push(input);
}).on('close', () => {
  const [numPeople, numMessages] = inputLines[0].split(' ').map(Number);
  const messages = inputLines.slice(1).map(line => line.split(' ').map(Number));

  // 检查输入范围,如果超出范围则输出 "Null"
  if (numPeople < 1 || numPeople >= 100000 || numMessages < 1 || numMessages >= 100000) {
    console.log('Null');
    return;
  }

  // 初始化数组,用于存储每个人的团队信息
  const parent = Array.from({ length: numPeople + 1 }, (_, i) => i);

  // 遍历消息,根据指令处理团队关系
  for (const message of messages) {
    const [personA, personB, command] = message;

    // 检查输入范围,如果超出范围则输出 "da pian zi"
    if (personA < 1 || personA > numPeople || personB < 1 || personB > numPeople) {
      console.log('da pian zi');
      continue;
    }

    // 如果指令为 0,则合并 personA 和 personB 所在的团队
    if (command === 0) {
      const rootA = find(personA, parent);
      const rootB = find(personB, parent);

      if (rootA !== rootB) {
        parent[rootB] = rootA;
      }
    }
    // 如果指令为 1,则判断 personA 和 personB 是否在同一个团队
    else if (command === 1) {
      console.log(find(personA, parent) === find(personB, parent) ? 'We are a team' : 'We are not a team');
    }
    // 如果指令为其他值,则输出 "da pian zi"
    else {
      console.log('da pian zi');
    }
  }
});

C++

#include <iostream>
#include <vector>

// 查找节点,用于判断两个人是否在同一个团队
int find(int x, std::vector<int> &parent) {
    if (parent[x] != x) {
        parent[x] = find(parent[x], parent);
    }
    return parent[x];
}

int main() {
    // 读取输入,获取人数和消息数量
    int numPeople, numMessages;
    std::cin >> numPeople >> numMessages;

    // 读取消息并存储到二维数组中
    std::vector<std::vector<int>> messages(numMessages, std::vector<int>(3));
    for (int i = 0; i < numMessages; i++) {
        std::cin >> messages[i][0] >> messages[i][1] >> messages[i][2];
    }

    // 检查输入范围,如果超出范围则输出 "Null"
    if (numPeople < 1 || numPeople >= 100000 || numMessages < 1 || numMessages >= 100000) {
        std::cout << "Null" << std::endl;
        return 0;
    }

    // 初始化数组,用于存储每个人的团队信息
    std::vector<int> parent(numPeople + 1);
    for (int i = 0; i < numPeople + 1; i++) parent[i] = i;

    // 遍历消息,根据指令处理团队关系
    for (const auto &message : messages) {
        int personA = message[0], personB = message[1], command = message[2];

        // 检查输入范围,如果超出范围则输出 "da pian zi"
        if (personA < 1 || personA > numPeople || personB < 1 || personB > numPeople) {
            std::cout << "da pian zi" << std::endl;
            continue;
        }

        // 如果指令为 0,则合并 personA 和 personB 所在的团队
        if (command == 0) {
            int rootA = find(personA, parent);
            int rootB = find(personB, parent);

            if (rootA != rootB) {
                parent[rootB] = rootA;
            }
        }
        // 如果指令为 1,则判断 personA 和 personB 是否在同一个团队
        else if (command == 1) {
            std::cout << (find(personA, parent) == find(personB, parent) ? "We are a team" : "We are not a team") << std::endl;
        }
        // 如果指令为其他值,则输出 "da pian zi"
        else {
            std::cout << "da pian zi" << std::endl;
        }
    }

    return 0;
}

C

#include <stdio.h>

// 查找某个节点的根节点(使用路径压缩来优化查找)
int find(int x, int parent[]) {
    if (parent[x] != x) {
        // 递归查找父节点并压缩路径
        parent[x] = find(parent[x], parent);
    }
    return parent[x];
}

int main() {
    int n, m;

    // 输入 n 和 m,表示人数和消息数
    if (scanf("%d %d", &n, &m) != 2) {
        // 输入读取错误
        printf("Null\n");
        return 0;
    }

    // 检查人数和消息数的合法性
    if (n < 1 || n >= 100000 || m < 1 || m >= 100000) {
        // 如果超出规定范围,输出 "Null"
        printf("Null\n");
        return 0;
    }

    // 初始化并查集数组,每个人初始为自己的团队
    int parent[n + 1];
    for (int i = 1; i <= n; i++) {
        parent[i] = i; // 初始时,每个人的父节点是自己
    }

    // 处理每条消息
    for (int i = 0; i < m; i++) {
        int a, b, c;

        // 读取消息 a, b, c
        if (scanf("%d %d %d", &a, &b, &c) != 3) {
            // 如果输入格式有误,忽略本条消息
            continue;
        }

        // 检查 a 和 b 是否在合法范围内
        if (a < 1 || a > n || b < 1 || b > n) {
            printf("da pian zi\n"); // 输入不合法,输出 "da pian zi"
            continue;
        }

        // 处理指令
        if (c == 0) {
            // 指令为 0,表示将 a 和 b 合并到同一个团队中
            int rootA = find(a, parent); // 查找 a 的根节点
            int rootB = find(b, parent); // 查找 b 的根节点

            // 如果 a 和 b 不在同一个团队,合并它们
            if (rootA != rootB) {
                parent[rootB] = rootA; // 将 b 的根节点指向 a 的根节点
            }
        } else if (c == 1) {
            // 指令为 1,表示判断 a 和 b 是否在同一个团队
            if (find(a, parent) == find(b, parent)) {
                printf("We are a team\n"); // a 和 b 在同一个团队
            } else {
                printf("We are not a team\n"); // a 和 b 不在同一个团队
            }
        } else {
            // 其他不合法的指令
            printf("da pian zi\n");
        }
    }

    return 0;
}
#华为##OD##牛客创作赏金赛#

主要记录自己的刷题日常,学而时习之。

全部评论
膜拜大佬
点赞 回复 分享
发布于 11-13 17:54 广东

相关推荐

刚刚做了华为Java机考,人是懵的。三道题两小时,每道题都看着不难都有思路结果写完过了测试一提交只有10%通过率,最后只有第一题提到了85%,最后算下来135分过不了150线,我愧对期待值拉满的HR,愧对我自己的复习。。。还是没刷够和基础不足,但至少把题目发这里大伙帮我解决一下这个遗憾吧。(不是,哥们。发现十拿九稳的主思路只能过10%,真得懵吧)第一题100:游客参观总时长问游乐园每天开放多久能招待所有游客。游乐园每一段时间能接受任意个数游客。每一行给一个游客的参观时长[1,5],[1,2],&nbsp;[10,11],输出总时长&nbsp;4+1=5.&nbsp;数值全在10^6以下。(确认输入无误)我一开始想做合并时间段最后算累加,结果Arraylist写下来边界判断什么的瞎闹连测试案例都过不了。三道题都写完之后回来检查,改了方法,求出参观时长的最大值,以它为长度建立空数组,再遍历游客时间插入1.最后数1,数到0就断掉算长度累加。通过率到了85%,但是给的反馈是测试用例运行错误,不是超时,我就只能继续检查下一题去了。(没想到后续检查没救得了我)第二题200:字符串集合求交集(这个是我最懵的,教教)(不需要检查输入)题目意思非常简单,给你输入几个字符串集合,{3(长度)&nbsp;123&nbsp;456&nbsp;789}第一个集合.{&nbsp;2&nbsp;456&nbsp;789}第二个集合。输出每个集合交集最大的集合和长度&nbsp;2&nbsp;2&nbsp;\n&nbsp;1&nbsp;2&nbsp;。字符串完全相等就是交集的元素。就这么简单。&nbsp;我Hashmap存集合的输入顺序,也就是集合的序号,value存的是字符串ArrayList。然后按总输出的值遍历这个输入顺序下标获取那个字符串集合,然后和另一个下标对应的字符串集合遍历。四层遍历求个相等的情况+1,记录最长值和最长集合序号。过了测试例以后提交,10%,还是答案错误不是超时,我人懵了,回来检查的时候也还是懵的。各路大神务必教教我这必须查相等的遍历为什么过了基础例子然后只能过10%的测试。有什么优化办法能既考虑边界值也能简化时长的?第三题300:摘水果也蛮直白的,给你个正方形地图,然后每个格子上是水果的数量,如果不能走就是-1.&nbsp;果农要从左上角走到右下角,只能向下或向右。走到右下角以后他再从右下角折回来走(没限制怎么走回来)到左上角,问你他能采摘的最大水果数量。这题我承认肯定是算法没想明白,漏了什么很关键的东西。(应该早点放弃检查的,很烦)这题我一开始想搞个递归往下找记录总数改变地图数字,然后往上找再递归找路最后加起来。但是写出来了向下找路然后发现这个找路和求最大值的路想做复原太诡异了,(现在想想完全可以找到路了记下来再找到最大值,很有可能能避免一些case)就放弃了递归投向动态规划。我累加了一次dp所有值抵达右下角以后,发现这个格子里的值正好是走下去走上来能拿到的最大值,想了一下应该也对,如果从左上角走不下来,那也不可能从那条路折回来,所有通路值加到最后应该就是答案。(难道说!是多个通路,只能取2条最大?!状态转移没这么简单才对!)状态转移方程就是等于非-1的左侧和上侧的格子的值相加再加上本来格子里的值。如果左上都是-1那我直接设为0.(难道该设为-1?复盘才发现槽点太多)(给地图加了一行一列全设为0,从1开始遍历到n。)往回走也不可能走这里。最后得分10%。求解!
牛客141057821号:我用python做的 第一道题记得leetcode有原题,先用开始参观时间sort一下然后指针遍历求set union 第二道题我python暴力解法全过。。 第三道题我是两遍dp,已从从左上到右下一次右下到左上,中间把第一次遍历走过的格子设成0就完了。 话说150是分数线吗?可以问下哪里的消息么
查看3道真题和解析 投递华为等公司10个岗位
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务