【备战秋招】每日一题:4月18日美团春招:题面+题目思路 + C++/python/js/Go/java带注释

news2024/11/17 13:55:52

2023大厂笔试模拟练习网站(含题解)
www.codefun2000.com
最近我们一直在将收集到的各种大厂笔试的解题思路还原成题目并制作数据,挂载到我们的OJ上,供大家学习交流,体会笔试难度。现已录入200+道互联网大厂模拟练习题,还在极速更新中。欢迎关注公众号“塔子哥学算法”获取最新消息。

提交链接:

https://codefun2000.com/p/P1138

为了更好的阅读体检,可以查看OJ上的题解。进入提交链接,点击右边菜单栏的"查看塔子哥的题解"

在线评测链接:P1170

题目描述:

塔子哥是一位著名的冒险家,他经常在各种森林里探险。今天,他来到了道成林,这是一片美丽而神秘的森林。在探险途中,他遇到了一棵 n 个节点的树,树上每个节点都被涂上了红、绿、蓝三种颜色之一。

塔子哥发现,如果这棵树同时存在一个红色节点、一个绿色节点和一个蓝色节点,那么我们就称这棵树是多彩的。很幸运,他发现这棵树最初就是多彩的。

但是,在探险的过程中,塔子哥发现这棵树上有一条边非常重要,如果砍掉这条边,就可以把这棵树分成两个部分。他想知道,有多少种砍法可以砍掉这条边,使得砍完之后形成的两棵树都是多彩的。

输入描述

第一行个整数 n ,表示节点个数

第二行 n-1 个整数 p_2,p_3,...,p_np_i表示树上 i 和 p 两点之间有一条边。保证给出的定是一棵树。

第三行一个长度为 n 的字符串,第 i 个字符表示第 i 个节点的初始颜色。其中 R 表示红色, G 表示绿色, B 表示蓝色。

保证字符串只由这三种大写字母构成对于全部数据, 3\le n\le 10^5

输出描述

输出一行,一个正整数,表示答案。

样例

输入

7
​
1 2 3 1 5 5
​
GBGRRBB

输出

1

思路

树的遍历 + DFS

考虑以 1 号点为根构造一棵树。

对于每条边 u-v,其中 v 是 u 的儿子。

则砍掉 u-v 这条边,将树分为了 以 v 为根的子树以 0 为根的树上砍掉以 v 为根的子树 这两部分。

故需要知道这两部分的 RGB 的数量。

先一遍 dfs 统计以每个点为根的子树中 RGB 的数量,再一遍 dfs 枚举断点每条边,然后统计两个新的部分中 RGB 的数量。

时间复杂度:O(n)

类似题目推荐

点评:树上dfs问题在LeetCode上有非常多的例题,并且在2023年春招过程中考了114514次。望周知。

LeetCod

  1. 589. N 叉树的前序遍历

  2. 429. N 叉树的层序遍历

  3. 590. N 叉树的后序遍历

Codefun2000

难度按序号递增,一次刷个够!

1.P1224 携程 2023.04.15-春招-第三题-魔法之树

2.P1159. 2022年清华大学(深圳)保研夏令营机试题-第一题-树上计数

3.P1065. 米哈游 2023.3.5-最长的通讯路径

4.P1196 华为 2023-04-19-第二题-塔子哥出城

5.P1044. 拼多多内推笔试-2023.2.22.投喂珍珠

6.P1193. 腾讯音乐 2023.04.13-暑期实习-第二题-价值二叉树

7.P1081. 百度 2023.3.13-第三题-树上同色连通块

更多请见:知识点分类-训练-深度优先搜索专栏

代码

CPP

#include <bits/stdc++.h>
using namespace std;
​
// 将字母映射到一个ID
int idx(char ch) {
    if (ch == 'R') return 0;
    else if (ch == 'G') return 1;
    return 2;
}
​
// 判断两个子树 A 和删掉了子树 A 的树中每个颜色是否都还存在
bool check(vector<int>& A, vector<int>& B) {
    for (int i = 0; i < 3; ++i) {
        if (A[i] == 0 || B[i] == A[i]) {
            return false;
        }
    }
    return true;
}
​
int main()
{
    int n;
    cin >> n;
​
    vector<vector<int>> g(n);
    for (int i = 2; i <= n; ++i) {
        int p; cin >> p;
        g[i - 1].emplace_back(p - 1);
        g[p - 1].emplace_back(i - 1);
    }
​
    string s;
    cin >> s;
​
    vector<vector<int>> cnt(n, vector<int>(3, 0));
​
    int ans = 0;
    // first = true 表示是在统计整个树的 RGB 
    // first = false 表示是在统计答案
    function<void(int,int,bool)> dfs = [&](int u, int fa, bool first) {
        for (int v: g[u]) {
            if (v == fa) continue;
            dfs(v, u, first);
            if (first) {
                // 累加子树中的所有 RGB
                for (int j = 0; j < 3; ++j) cnt[u][j] += cnt[v][j];
            } else {
                // 如果断掉 u-v 这条边,使得两棵树都有 RGB,则答案 + 1
                if (check(cnt[v], cnt[0])) ans += 1;
            }
        }
        if (first) cnt[u][idx(s[u])] += 1;
    };
​
    dfs(0, -1, true);
    dfs(0, -1, false);
​
    cout << ans << "\n";
​
    return 0;
}

python

# 将字母映射到一个ID
def idx(ch):
    if ch == 'R':
        return 0
    elif ch == 'G':
        return 1
    return 2
​
​
# 判断两个子树 A 和删掉了子树 A 的树中每个颜色是否都还存在
def check(A, B):
    for i in range(3):
        if A[i] == 0 or B[i] == A[i]:
            return False
    return True
​
​
n = int(input())
​
g = [[] for _ in range(n)]
p = list(map(int, input().split(" ")))
for i in range(2, n + 1):
    g[i - 1].append(p[i - 2] - 1)
    g[p[i - 2] - 1].append(i - 1)
​
s = input()
​
cnt = [[0] * 3 for _ in range(n)]
​
ans = 0
​
​
# first = true 表示是在统计整个树的 RGB 
# first = false 表示是在统计答案
def dfs(u, fa, first):
    global ans
    for v in g[u]:
        if v == fa:
            continue
        dfs(v, u, first)
        if first:
            # 累加子树中的所有 RGB
            for j in range(3):
                cnt[u][j] += cnt[v][j]
        else:
            # 如果断掉 u-v 这条边,使得两棵树都有 RGB,则答案 + 1
            if check(cnt[v], cnt[0]):
                ans += 1
    if first:
        cnt[u][idx(s[u])] += 1
​
​
dfs(0, -1, True)
dfs(0, -1, False)
​
print(ans)

Java

import java.util.*;
​
public class Main {
​
    static int ans;
​
    public static int idx(char ch) {
        if (ch == 'R') return 0;
        else if (ch == 'G') return 1;
        return 2;
    }
​
    public static boolean check(int[] A, int[] B) {
        for (int i = 0; i < 3; ++i) {
            if (A[i] == 0 || B[i] == A[i]) {
                return false;
            }
        }
        return true;
    }
​
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
​
        List<List<Integer>> g = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            g.add(new ArrayList<>());
        }
​
        for (int i = 2; i <= n; i++) {
            int p = sc.nextInt();
            g.get(i-1).add(p-1);
            g.get(p-1).add(i-1);
        }
​
        String s = sc.next();
​
        int[][] cnt = new int[n][3];
​
        // first = true 表示是在统计整个树的 RGB 
        // first = false 表示是在统计答案
        dfs(0, -1, true, g, s, cnt);
        ans = 0;
        dfs(0, -1, false, g, s, cnt);
​
        System.out.println(ans);
    }
​
    public static void dfs(int u, int fa, boolean first, List<List<Integer>> g, String s, int[][] cnt) {
        for (int v : g.get(u)) {
            if (v == fa) continue;
            dfs(v, u, first, g, s, cnt);
            if (first) {
                // 累加子树中的所有 RGB
                for (int j = 0; j < 3; ++j) cnt[u][j] += cnt[v][j];
            } else {
                // 如果断掉 u-v 这条边,使得两棵树都有 RGB,则答案 + 1
                if (check(cnt[v], cnt[0])) ans += 1;
            }
        }
        if (first) cnt[u][idx(s.charAt(u))] += 1;
    }
}

Go

package main
​
import (
    "fmt"
)
​
// 将字母映射到一个ID
func idx(ch byte) int {
    if ch == 'R' {
        return 0
    } else if ch == 'G' {
        return 1
    }
    return 2
}
​
// 判断两个子树 A 和删掉了子树 A 的树中每个颜色是否都还存在
func check(A []int, B []int) bool {
    for i := 0; i < 3; i++ {
        if A[i] == 0 || B[i] == A[i] {
            return false
        }
    }
    return true
}
​
func main() {
    var n int
    fmt.Scan(&n)
​
    g := make([][]int, n)
    for i := 2; i <= n; i++ {
        var p int
        fmt.Scan(&p)
        g[i-1] = append(g[i-1], p-1)
        g[p-1] = append(g[p-1], i-1)
    }
​
    var s string
    fmt.Scan(&s)
​
    cnt := make([][]int, n)
    for i := range cnt {
        cnt[i] = make([]int, 3)
    }
​
    ans := 0
    // first = true 表示是在统计整个树的 RGB
    // first = false 表示是在统计答案
    var dfs func(u, fa int, first bool)
    dfs = func(u, fa int, first bool) {
        for _, v := range g[u] {
            if v == fa {
                continue
            }
            dfs(v, u, first)
            if first {
                // 累加子树中的所有 RGB
                for j := 0; j < 3; j++ {
                    cnt[u][j] += cnt[v][j]
                }
            } else {
                // 如果断掉 u-v 这条边,使得两棵树都有 RGB,则答案 + 1
                if check(cnt[v], cnt[0]) {
                    ans += 1
                }
            }
        }
        if first {
            cnt[u][idx(s[u])] += 1
        }
    }
​
    dfs(0, -1, true)
    dfs(0, -1, false)
​
    fmt.Println(ans)
}

Js

process.stdin.resume();
process.stdin.setEncoding('utf-8');
let input = '';
process.stdin.on('data', (data) => {
    input += data;
    return;
});
process.stdin.on('end', () => {
    const lines = input.trim().split('\n');
    const n = parseInt(lines[0]);
    const g = new Array(n).fill(0).map(() => []);
    p = lines[1].split(' ').map(x => parseInt(x));
    for (let i = 2; i <= n; i++) {
        g[i - 1].push(p[i - 2] - 1);
        g[p[i - 2] - 1].push(i - 1);
    }
    const s = lines[2].trim();
    const cnt = new Array(n).fill(0).map(() => new Array(3).fill(0));
    let ans = 0;
    // first = true 表示是在统计整个树的 RGB
    // first = false 表示是在统计答案
    const dfs = (u, fa, first) => {
        for (let i = 0; i < g[u].length; i++) {
            const v = g[u][i];
            if (v === fa) continue;
            dfs(v, u, first);
            if (first) {
                // 累加子树中的所有 RGB
                for (let j = 0; j < 3; j++) {
                    cnt[u][j] += cnt[v][j];
                }
            } else {
                // 如果断掉 u-v 这条边,使得两棵树都有 RGB,则答案 + 1
                if (check(cnt[v], cnt[0])) ans += 1;
            }
        }
        if (first) cnt[u][idx(s[u])] += 1;
    };
    dfs(0, -1, true);
    dfs(0, -1, false);
    console.log(ans);
});
​
// 将字母映射到一个ID
function idx(ch) {
    if (ch === 'R') return 0;
    else if (ch === 'G') return 1;
    return 2;
}
​
// 判断两个子树 A 和删掉了子树 A 的树中每个颜色是否都还存在
function check(A, B) {
    for (let i = 0; i < 3; i++) {
        if (A[i] === 0 || B[i] === A[i]) {
            return false;
        }
    }
    return true;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/634405.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

8 channel、反射、网络编程【Go语言教程】

8 channel、反射、网络编程【Go语言教程】 1 channel 1.1 概念及快速入门 channel:管道&#xff0c;主要用于不同goroutine之间的通讯 需求&#xff1a;现在要计算 1-200 的各个数的阶乘&#xff0c;并且把各个数的阶乘放入到 map 中。最后显示出来。要求使用 goroutine 完成…

[LeetCode周赛复盘] 第 349 场周赛20230611

[LeetCode周赛复盘] 第 349 场周赛20230611 一、本周周赛总结6470. 既不是最小值也不是最大值1. 题目描述2. 思路分析3. 代码实现 6465. 执行子串操作后的字典序最小字符串1. 题目描述2. 思路分析3. 代码实现 6449. 收集巧克力1. 题目描述2. 思路分析3. 代码实现 6473. 最大和…

测试老鸟总结,接口自动化测试用例设计编写,高级测试之路...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 接口信息来源 与…

百度图像识别 API

首先预览下效果 feaa250077a543a39f037ae8e78a3e80~tplv-k3u1fbpfcp-zoom-in-crop-mark:1512:0:0:0.awebp (640594) (byteimg.com) 从以上预览图中可看出&#xff0c;每张图片识别出5条数据&#xff0c;每条数据根据识别度从高往下排&#xff0c;每条数据包含物品名称、识别度…

VisualStdio中scanf报错问题

VisualStdio中scanf报错问题 目录 一&#xff0e; 概述二&#xff0e; 解决方法 一&#xff0e; 概述 报错代码及说明 报错代码为C4996 会在哪种编译器中报错&#xff1f; VisualStdio系列编译器 为什么会报错&#xff1f; 因为VisualStdio比较严谨&#xff0c;认为scanf不…

内网安全:横向传递攻击( RDP || Cobalt Strike )

内网安全&#xff1a;横向传递攻击&#xff08; RDP || Cobalt Strike &#xff09; 横向移动就是在拿下对方一台主机后&#xff0c;以拿下的那台主机作为跳板&#xff0c;对内网的其他主机再进行后面渗透&#xff0c;利用既有的资源尝试获取更多的凭据、更高的权限&#xff0…

【基础知识整理】时间复杂度 空间复杂度

概览 时间复杂度与空间复杂度的作用是在衡量一个算法的优劣性&#xff0c;以及在二者之间进行权衡&#xff0c;寻找二者的平衡点。 时间复杂度是指执行算法所需时间的增长率&#xff0c;而空间复杂度则是指执行算法所需存储空间的增长率。 高时间复杂度的算法可能需要在短时间…

合金氢化物动力学与瞬时流量

在经典的合金氢化物动力学描述中&#xff0c;有一种是用JMAK方程来描述和拟合合金的吸放氢过程&#xff0c;方程很简洁&#xff1a;&#xff0c;其中是反应程度或者百分比&#xff0c;表示合金氢化物吸氢或者放氢的程度&#xff0c;是该合金吸氢或放氢的一种特征常数&#xff0…

使用wab2app将网页打包成APK

前言 通过开源项目ChatGPT-Next-Web部署完了私人网页ChatGPT&#xff0c;为了使访问更加便捷&#xff0c;便想着使用wab2app打包为APK&#xff0c;虽然最终达成了效果&#xff0c;可一路走来遇到了很多坑儿&#xff0c;记录下 打包流程 有要打包的网站和软件HBuilder X&…

【Kubernetes存储篇】持久化存储PV、PVC详解

文章目录 一、PV、PVC持久化存储理论1、PV、PVC是什么&#xff1f;2、PV的供应方式3、PV、PVC的回收策略 二、案例&#xff1a;PV、PVC持久化存储案例演示1、搭建NFS服务端2、创建PV&#xff0c;并使用NFS共享存储3、创建PVC&#xff0c;并和PV绑定4、创建Pod&#xff0c;并挂载…

docker中运行PostgreSQL容器

我们如何在docker中运行postgresql容器&#xff0c;要进过如下几个步骤就可以了。 拉取postgresql容器 docker pull postgres:latest使用上述命令将从 Docker Hub 存储库中提取最新可用版本的 PostgreSQL。 从 PostgreSQL 服务器 Docker 镜像运行容器 在部署之前&#xff0c;…

2023年6月DAMA-CDGA/CDGP数据治理工程师认证报名特惠

DAMA认证为数据管理专业人士提供职业目标晋升规划&#xff0c;彰显了职业发展里程碑及发展阶梯定义&#xff0c;帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力&#xff0c;促进开展工作实践应用及实际问题解决&#xff0c;形成企业所需的新数字经济下的核心职业…

WinDbg安装入坑3(C#)

由于作者水平有限&#xff0c;如有写得不对的地方&#xff0c;请指正。 使用WinDbg的过程中&#xff0c;坑特别的多&#xff0c;对版本要求比较严格&#xff0c;如&#xff1a; 1 32位应用程序导出的Dump文件要用32位的WinDbg打开&#xff0c;想要没有那么多的问题&#xf…

Xcode 15 beta (15A5160n) - Apple 平台 IDE

Xcode 15 beta (15A5160n) - Apple 平台 IDE IDE for iOS/iPadOS/macOS/watchOS/tvOS/visonOS 请访问原文链接&#xff1a;https://sysin.org/blog/apple-xcode-14/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Xcode 15 使…

windows系统cmd命令设置别名,并添加到环境变量

众所周知&#xff0c;Linux 命令很强大&#xff0c;使用起来也很方便&#xff0c;但是想在 windows 系统上使用 Linux 命令有些困难&#xff0c;要么下载第三方终端工具&#xff0c;要么就是安装一系列命令环境。 作为一个前端开发&#xff0c;其实可以全局安装一下 npm 命令行…

分库分表-ShardingSphere

分库分表拆常见分方法与特点 分片策略 数据分布 以后扩展 基于Hash&#xff1a;hash(分片键)%分片数 数据分布均匀 不易扩容&#xff0c;扩容需要数据迁移 范围分片&#xff1a;例如按年分&#xff0c;按月&#xff0c;按日 数据分表可能不均匀 易扩展&#xff0c;扩展…

API自动化测试利器Postman,帮助你更好地进行 API 自动化测试

目录 前言&#xff1a; 一、基本功能 二、测试工具 三、示例 前言&#xff1a; Postman 是一个易于使用的 API 开发和测试工具&#xff0c;可以在其中快速构建、测试和文档化 Web API。Postman 提供了一个直观的用户界面&#xff0c;可以轻松地创建 HTTP 请求、测试响应、…

深入解析XMLHttpRequest:实现异步通信的利器

文章目录 介绍什么是XMLHttpRequest&#xff1f;XMLHttpRequest的基本用法1.创建XMLHttpRequest对象2.配置请求3.发送请求 XMLHttpRequest 属性sendreadyStatestatusstatusTextresponseresponseTextresponseTyperesponseURLtimeoutwithCredentials 异步请求与同步请求请求类型和…

淡季,老手买入的季节。

刚在刷抖音&#xff0c;刷到马云的视频。心里在想&#xff1a;这么大的企业家大富豪怎么会哽咽呢&#xff1f;他缺钱吗&#xff1f;他需要为生存奋斗吗&#xff1f; 他当然不缺钱&#xff0c;也不需要为生存去奋斗。如果以家庭生活支出来算&#xff0c;他的钱够几代儿孙挥霍了。…

漂亮国因一颗气球而疯狂给质量团队带来的启示

最近漂亮国因为我国的一颗漂洋过海的淘气的民用气球而疯狂。这颗气球成功躲过了号称全球最先进的防空系统&#xff0c;跨越大半个漂亮国&#xff0c;直到被一居民拍照无意间发现&#xff0c;漂亮国才反应过来。多次派战斗机拦截无果&#xff0c;在气球降到15km后&#xff0c;F2…