【2023-10-15】网易秋招笔试四道编程题解

本文分享了2023年网易秋季校招笔试的四道编程题目,包括最小登录天数、整数切分、语言交流和路径均值问题的详细解题思路与Python、Java代码实现。
摘要由CSDN通过智能技术生成

恭喜发现宝藏!搜索公众号【TechGuide】回复公司名,解锁更多新鲜好文和互联网大厂的笔经面经。
作者@TechGuide【全网同名】

订阅专栏【进阶版】2023最新大厂笔试真题 & 题解,不容错过的宝藏资源!

第一题:最小登录天数

题目描述

dd最近迷上了玩阴阳师,现在眼前有一个永久勾玉卡,她在思考应不应该花费一定勾玉购买。

已知永久勾玉卡的价格是a勾玉,购买了永久勾玉卡之后每天登录游戏会返还6勾玉,但是三分钟热度的dd不知道自己能坚持玩几天,她想知道买了永久勾玉卡之后至少登录多少天她才可以回本。

输入描述

第一行一个正整数T(1<=T<=500),表示询问组数

接下来T行,每行两个正整数a,b,含义如上(1<=a,b<=10000000)

输出描述

T行,每行一个数,表示对应的答案。

样例

输入

3
10 1
10 2
10 3

输出

10
5
4

思路

签到题,直接看代码。

代码

Python版本

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int t = scanner.nextInt();
        while (t-- > 0) {
            int a = scanner.nextInt();
            int b = scanner.nextInt();
            System.out.println((a / b) + (a % b != 0));
        }
    }
}
# vx公众号关注TechGuide,代码可能需要少量调试。

Java版本

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int t = scanner.nextInt();
        while (t-- > 0) {
            int a = scanner.nextInt();
            int b = scanner.nextInt();
            System.out.println((a / b) + (a % b != 0));
        }
    }
}
// vx公众号关注TechGuide,代码可能需要少量调试。

第二题:整数切分

题目描述

小盖拿到了一个正整数。她准备把这个正整数切成若干个不大于 100 的数然后求和。小盖希望最终的和尽可能大,你能帮帮她吗?

输入描述

一个正整数x。

1<=x<=10^10000

输出描述

一个整数,代表切割后最大的和。

样例

输入

12345

输出

69

样例说明

切割成 1+23+45 即可。

思路

依然是动态规划,维护一个 dp数组,其中 dp[i] 表示从第1位到第i位的切割后的最大和。通过迭代计算 dp 数组,最终 dp[n] 即为切割后最大的和。

代码

Python版本

def solve():
    x = input()
    n = len(x)
    dp = [0] * (n + 1)

    for i in range(1, n + 1):
        cur = 0
        base = 1
        for j in range(i, max(1, i - 2), -1):
            cur += int(x[j - 1]) * base
            base *= 10
            if cur < 100:
                dp[i] = max(dp[i], cur + dp[j - 1])

    print(dp[n])

if __name__ == "__main__":
    solve()

# vx公众号关注TechGuide,代码可能需要少量调试。

Java版本

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String x = scanner.next();
        int n = x.length();
        int[] dp = new int[n + 1];

        for (int i = 1; i <= n; i++) {
            int cur = 0;
            int base = 1;
            for (int j = i; j >= Math.max(1, i - 2); j--) {
                cur += (x.charAt(j - 1) - '0') * base;
                base *= 10;
                if (cur < 100) {
                    dp[i] = Math.max(dp[i], cur + dp[j - 1]);
                }
            }
        }

        System.out.println(dp[n]);
    }
}

// vx公众号关注TechGuide,代码可能需要少量调试。

第三题:语言交流

题目描述

小盖和朋友一共个人,一共有 m 种语言,每个人可能会多种语言,两个人可以交流当且仅当他们至少有一种共同的语言。小盖想知道,她和朋友们最少需要学多少种语言,任何人都可以和其他人进行交流。如果 A和B可以交流,B和C可以交流,那么A和C也可以间接的交流。

输入描述

第一行包含两个正整数n和,表示小盖的朋友的数量和语言的数量
接下来n行,每行第一个数ki,表示第i个人会ki种语言,接下来ki个数ai1,ai2…,aik,表示第i个人会的语言的编号。
1<=n<=1000
1<=m<=1000
1<=aij<=m
0<=ki<=m

输出描述

输出一个整数,表示小盖和朋友们最少需要学习的语言数量。

样例

输入

3 3
1 1
1 2
1 3

输出

2

样例说明

第二个人学习第一种语言,第三个人学习第二种语言,这样第一个人可以和第二个人交流,第二个人可以和第三个人交流。所有人都可以互相直接或间接交流。

思路

并查集,判断两个人是否有至少一种共同的语言,然后合并这两个人所在的集合,集合的数量就是小盖和朋友们最少需要学习的语言数量。

代码

Python版本

def father(i, f):
    if f[i] == i:
        return i
    f[i] = father(f[i], f)
    return f[i]

def connect(i, j, f):
    fi = father(i, f)
    fj = father(j, f)
    if fi != fj:
        f[fi] = fj

def solve():
    n, m = map(int, input().split())
    f = [i for i in range(n)]
    first = [-1] * (m + 1)

    for i in range(n):
        cnt, *langs = map(int, input().split())
        for lang in langs:
            if first[lang] == -1:
                first[lang] = i
            else:
                connect(i, first[lang], f)

    has = any(first[i] != -1 for i in range(1, m + 1))

    if not has:
        print(n)
        return

    ans = sum(1 for i in range(n) if father(i, f) == i) - 1
    print(ans)

if __name__ == "__main__":
    solve()

# vx公众号关注TechGuide,代码可能需要少量调试。

Java版本

import java.util.Arrays;
import java.util.Scanner;

public class LanguageLearning {

    public static void main(String[] args) {
        solve();
    }

    static void solve() {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        int[] f = new int[n];

        for (int i = 0; i < n; i++) {
            f[i] = i;
        }

        int[] first = new int[m + 1];
        Arrays.fill(first, -1);

        for (int i = 0; i < n; i++) {
            int cnt = scanner.nextInt();
            for (int j = 0; j < cnt; j++) {
                int lang = scanner.nextInt();
                if (first[lang] == -1) {
                    first[lang] = i;
                } else {
                    connect(i, first[lang], f);
                }
            }
        }

        boolean has = false;
        for (int i = 1; i <= m; i++) {
            if (first[i] != -1) {
                has = true;
            }
        }

        if (!has) {
            System.out.println(n);
            return;
        }

        int ans = 0;
        for (int i = 0; i < n; i++) {
            if (father(i, f) == i) {
                ans++;
            }
        }
        System.out.println(ans - 1);
    }

    static int father(int i, int[] f) {
        if (f[i] == i) {
            return i;
        }
        return f[i] = father(f[i], f);
    }

    static void connect(int i, int j, int[] f) {
        int fi = father(i, f);
        int fj = father(j, f);
        if (fi != fj) {
            f[fi] = fj;
        }
    }
}

// vx公众号关注TechGuide,代码可能需要少量调试。

第四题:路径均值

题目描述

小盖拿到了一棵树。她有多次查询,每次查询一条路上所有节点的平均数是多少。你帮帮她吗?

输入描述

第一行输入一个正整数n,代表树的节点数量。
第二行输入n个正整数ai,第i个正整数代表号节点的权值
接下来的n-1行,每行输入两个正整数u,v,代表节点u和节点u有一条边连接
接下来的一行输入一个正整数 q,代表查询次数。
接下来的9行,每行输入两个正整数x和y,代表一次查询,该次查询为节点x到节点Y路径上所有节点的平均数.
1<=n,q<=10^5
1<=ai<=10^9

输出描述

输出q行,每行输入一个整数,代表路径上的所有节点的平均数。

样例

输入

3 
4 5 6
1 2
1 3
2
1 2
2 3

输出

500000008
5

思路

dfs,保存每个节点的权值和以及节点数量,计算两个节点的最近公共祖先和路径上所有节点的平均值。

代码

Python版本

def mod_pow(a, b, mod):
    if b == 0:
        return 1
    res = mod_pow(a, b // 2, mod)
    res = res * res % mod
    if b % 2 == 1:
        res = res * a % mod
    return res


def dfs1(g, sum, cnt, a, cur, f):
    if f != -1:
        sum[cur] += sum[f]
        cnt[cur] += cnt[f]
    sum[cur] += a[cur]
    cnt[cur] += 1
    for next_node in g[cur]:
        if next_node == f:
            continue
        dfs1(g, sum, cnt, a, next_node, cur)


def dfs2(g, fa, dep, root, fno):
fa[root][0] = fno
dep[root] = dep[fa[root][0]] + 1
for i in range(1, 31):
fa[root][i] = fa[fa[root][i - 1]][i - 1]
sz = len(g[root])
for i in range(sz):
if g[root][i] == fno:
continue
dfs2(g, fa, dep, g[root][i], root)

def lca(x, y, fa, dep):
if dep[x] > dep[y]:
x, y = y, x
tmp = dep[y] - dep[x]
j = 0
while tmp > 0:
if tmp & 1:
y = fa[y][j]
j += 1
tmp >>= 1
if y == x:
return y
for j in range(30, -1, -1):
if fa[x][j] != fa[y][j]:
x = fa[x][j]
y = fa[y][j]
return fa[y][0]

def solve():
n = int(input())
a = [0] + list(map(int, input().split()))
g = [[] for _ in range(n + 1)]
for _ in range(n - 1):
    u, v = map(int, input().split())
    g[u].append(v)
    g[v].append(u)

sum_values = [0] * (n + 1)
cnt_values = [0] * (n + 1)

dfs1(g, sum_values, cnt_values, a, 1, 0)

fa_values = [[0] * 31 for _ in range(n + 1)]
dep_values = [0] * (n + 1)

dfs2(g, fa_values, dep_values, 1, 0)

q = int(input())
for _ in range(q):
    u, v = map(int, input().split())
    lc = lca(u, v, fa_values, dep_values)
    tot = (sum_values[u] + sum_values[v] - 2 * sum_values[lc] + a[lc]) % MOD
    c = cnt_values[u] + cnt_values[v] - 2 * cnt_values[lc] + 1
    inv = mod_pow(c, MOD - 2, MOD)
    ans = tot * inv % MOD
    print(ans)
    
if name == "main":
solve()
# vx公众号关注TechGuide,代码可能需要少量调试。

Java版本

import java.util.*;

public class Main {
    static final int MOD = 1000000007;

    static long modPow(long a, long b) {
        if (b == 0) return 1;
        long res = modPow(a, b / 2);
        res = res * res % MOD;
        if (b % 2 == 1) {
            res = res * a % MOD;
        }
        return res;
    }

    static void solve() {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] a = new int[n + 1];
        for (int i = 1; i <= n; i++) {
            a[i] = scanner.nextInt();
        }

        List<List<Integer>> g = new ArrayList<>();
        for (int i = 0; i <= n; i++) {
            g.add(new ArrayList<>());
        }

        for (int i = 0; i < n - 1; i++) {
            int u = scanner.nextInt();
            int v = scanner.nextInt();
            g.get(u).add(v);
            g.get(v).add(u);
        }

        long[] sum = new long[n + 1];
        int[] cnt = new int[n + 1];

        dfs1(g, sum, cnt, a, 1, 0);

        int[][] fa = new int[n + 1][31];
        int[] dep = new int[n + 1];

        dfs2(g, fa, dep, 1, 0);

        int q = scanner.nextInt();
        for (int i = 0; i < q; i++) {
            int u = scanner.nextInt();
            int v = scanner.nextInt();
            int lc = lca(u, v, fa, dep);
            long tot = sum[u] + sum[v] - 2 * sum[lc] + a[lc];
            tot %= MOD;
            long c = cnt[u] + cnt[v] - 2 * cnt[lc] + 1;
            long inv = modPow(c, MOD - 2);
            long ans = tot * inv % MOD;
            System.out.println(ans);
        }
    }

    static void dfs1(List<List<Integer>> g, long[] sum, int[] cnt, int[] a, int cur, int f) {
        if (f != -1) {
            sum[cur] += sum[f];
            cnt[cur] += cnt[f];
        }
        sum[cur] += a[cur];
        cnt[cur]++;
        for (int next : g.get(cur)) {
            if (next == f) continue;
            dfs1(g, sum, cnt, a, next, cur);
        }
    }

    static void dfs2(List<List<Integer>> g, int[][] fa, int[] dep, int root, int fno) {
        fa[root][0] = fno;
        dep[root] = dep[fa[root][0]] + 1;
        for (int i = 1; i < 31; ++i) {
            fa[root][i] = fa[fa[root][i - 1]][i - 1];
        }
        int sz = g.get(root).size();
        for (int i = 0; i < sz; ++i) {
            if (g.get(root).get(i) == fno) continue;
            dfs2(g, fa, dep, g.get(root).get(i), root);
        }
    }

    static int lca(int x, int y, int[][] fa, int[] dep) {
        if (dep[x] > dep[y]) {
            int temp = x;
            x = y;
            y = temp;
        }
        int tmp = dep[y] - dep[x];
        for (int j = 0; tmp > 0; ++j, tmp >>= 1) {
            if ((tmp & 1) == 1) y = fa[y][j];
        }
        if (y == x) return y;
        for (int j = 30; j >= 0; --j) {
            if (fa[x][j] != fa[y][j]) {
                x = fa[x][j];
                y = fa[y][j];
            }
        }
        return fa[y][0];
    }

    public static void main(String[] args) {
        solve();
    }
}

// vx公众号关注TechGuide,代码可能需要少量调试。
  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TechGuide

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值