用友笔试 用友笔试题 0801

笔试时间:2024年08月01日 提前批

历史笔试传送门:2023秋招笔试合集

第一题

题目:小友的生产线

小友设计了一条新的生产线,在该条生产线上共有0-n种工序。每种工序之间可能存在上下游关系,如果一种工序没有下游工序,则为终点工序。如果一种工序其所有可能下游工序均可到达终点工序,则称该工序为合规工序。给你一个有向图,其中有n个节点,表示不同种工序,以及不同工序之间的关系,请计算该条生产线中,所有的合规工序,并按照升序排列。

注意:终点工序无下游工序,默认为合规工序。

输入描述

第一行输入正整数n,表示共有n个工序节点;

接下来n行,每行有j(1<=j<n)个数,表示工序节点i与其余j个工序节点上下游关系。

注意:若工序节点i为终点工序,则j=1,且数值为-1。

输出描述

输出一个数组,用来表示所有的合规工序,并按照升序排列。

补充说明:n == graph.length、1 <= n <= 104、0 <= n[i].length <= n、-1 <= n[i][j] <= n - 1、n[i] 按严格递增顺序排列,图中可能包含自环。

样例输入一

5

1 2 3 4

1 2

3 4

0 4

-1

样例输出一

4

说明:只有工序4是终点工序,即为合规工序

样例输入二

7

1 2

2 3

5

0

5

-1

-1

样例输出二

2 4 5 6

说明:工序5和6为终点工序,即为合规工序 工序2和4开始的所有下游工序最终都指向终点工序,按照升序排列最终结果为2,4,5,6。

参考题解

C++:[此代码未进行大量数据的测试,仅供参考]

Java:[此代码未进行大量数据的测试,仅供参考]

Python:[此代码未进行大量数据的测试,仅供参考]

第二题

题目:小友策划游戏人物

小友是一个游戏策划,他计划设计一个新人物,该人物的攻击模式较为特殊:他的附加攻击力可以拆分为n份(n>=2),这n份的乘积作为最终伤害值。游戏总监认为该人物过于超模(过于强大),要求对其附加攻击力增加上限限制。现在给你最终伤害值的上限和该人物的附加攻击力,请判断该人物的实际最终伤害值是否会超出给出的最终伤害值上限。

输入描述

输入两个数值,第一个数值为最终伤害值上限,第二个数值为该人物的附加攻击力。

例如:2920 22

2920为最终伤害值的上限

22为该人物的附加攻击力

输出描述

输入true或者false

true表示超出上限

false表示未超出上限

补充说明

最终伤害值上限不会超过int最大值

样例输入一

1 2

样例输出一

false

说明

最终伤害上限1

附加攻击力2

2=1+1

1*1=1

所以未超过上限

样例输入二

161 14

样例输出二

true

说明

14=3+3+3+3+2

3*3*3*3*2=162>161

所以超过上限

参考题解

动态规划

C++:[此代码未进行大量数据的测试,仅供参考]

#include <iostream>
#include <cmath>
using namespace std;

long long solve(long long n) {
    if (n <= 3) {
        return n - 1;
    }
    long long quotient = n / 3;
    long long remainder = n % 3;
    if (remainder == 0) {
        return pow(3, quotient);
    } else if (remainder == 1) {
        return pow(3, quotient - 1) * 4;
    } else {
        return pow(3, quotient) * 2;
    }
}

int main() {
    long long limit, power;
    cin >> limit >> power;
    long long ans = solve(power);
    if (ans > limit) {
        cout << "true" << endl;
    } else {
        cout << "false" << endl;
    }
    return 0;
}

Java:[此代码未进行大量数据的测试,仅供参考]

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        long limit = scanner.nextLong();
        long power = scanner.nextLong();
        long ans = solve(power);
        if (ans > limit) {
            System.out.println("true");
        }
        else{
            System.out.println("false");
        }
    }

    static long solve(long n) {
        if (n <= 3) {
            return n - 1;
        }
        long quotient = n / 3;
        long remainder = n % 3;
        if (remainder == 0) {
            return (long) Math.pow(3, quotient);
        } else if (remainder == 1) {
            return (long) Math.pow(3, quotient - 1) * 4;
        } else {
            return (long) Math.pow(3, quotient) * 2;
        }
    }
}

Python:[此代码未进行大量数据的测试,仅供参考]

limit, power = map(int, input().split())
dp = [-1]*(power+1)
def dfs(i):
    if i==2:return 1
    if dp[i]!=-1:return dp[i]
    res = 0
    for j in range(1,i//2+1):
        res = max(res, dfs(i-j)*j, j*(i-j))
    dp[i] = res
    return res

ans = dfs(power)
if ans > limit:
    print("true")
else:
    print("false")

第三题

题目:最佳工作任务安排

小友所在的部门在进行一系列复杂的开发项目。为了优化开发流程,部门要求工程师在不同的任务之间切换。每个任务有不同的执行时间,有些任务因为各种原因无法进行(标记为-1)。工程师可以在规定的跳跃范围内从一个任务跳到另一个任务,但每次执行任务需要消耗相应的时间。你的目标是找到一个从任务列表开头到结尾的执行顺序,使得总执行时间最小。如果存在多个总执行时间相同的顺序,返回按索引值更小优先的顺序。如果无法到达最后一个任务,返回一个空数组。

规则:

1.输入一个整数数组 tasks 表示任务执行时间,长度为 n。

2.输入一个整数 maxStep 表示单次切换任务的最大切换长度。

3.你从任务列表的第一个任务开始(tasks[0] 不是 -1)。

4.从任务 i 切换到任务 j,消耗的时间为 tasks[j]。

5.如果你当前位于任务 i,你只能跳到任务 i + k(满足 i + k <= n),其中 k 在范围 [1, maxStep] 内。

6.返回一个整数数组,包含你访问的任务索引顺序,使得总执行时间最小。如果存在多个总执行时间相同的顺序,返回索引值更小的顺序。

排序说明:

如果存在多个总执行时间相同的顺序:

假设方案 p1 = [Pa1, Pa2, ..., Pax] 和方案 p2 = [Pb1, Pb2, ..., Pbx]。

如果在两个方案中第一个不同的索引 j 处,Pa[j] 小于 Pb[j],则选择方案 p1。

如果所有索引都相同,但任务切换次数不同,则选择任务切换次数较少的一个方案。

提示:注意排序规则,如 1-2-3-4-5 和 1-4-5 , 假设两个方案所消耗的时间成本相同, 那么前面的方案更优。

输入描述

整数 N,代表任务 tasks 的长度

长度为 N 的数组 tasks 的各个元素

整数 M,代表每次切换任务的最大跳跃长度

输出描述

输出数组,代表总执行时间最短,并且索引值最小的执行方案。

补充说明:

1 <= tasks.length <= 1000

-1 <= tasks[i] <= 100

tasks[0] != -1

1 <= maxStep <= 100

样例输入一

5

1 2 4 -1 2

2

样例输出一

1 3 5

样例输入二

5

1 2 4 -1 2

1

样例输出二

[]

说明:

无法到达最后一个任务,输出字符串"[]"

参考题解

动态规划+路径回溯。

C++:[此代码未进行大量数据的测试,仅供参考]

#include <iostream>
#include <vector>
#include <climits>
#include <algorithm>

using namespace std;

int main() {
    // 读取输入
    int N, M;
    cin >> N;
    vector<int> task(N);
    for (int i = 0; i < N; ++i) {
        cin >> task[i];
    }
    cin >> M;

    // 初始化 dp 数组
    const int INF = INT_MAX; // 使用 INT_MAX 代替 inf
    vector<int> f(N, INF);
    f[0] = 0;
    vector<int> fm(N, -1);

    // 动态规划
    for (int i = 1; i < N; ++i) {
        if (task[i] == -1) continue;
        for (int k = 1; k <= M; ++k) {
            if (i - k < 0) break;
            if (f[i - k] + task[i] < f[i] && task[i - k] != -1) {
                f[i] = f[i - k] + task[i];
                fm[i] = i - k;
            }
        }
    }

    // 回溯找到路径
    vector<int> res;
    int index = N - 1;
    while (true) {
        if (index == 0) {
            res.push_back(1);
            break;
        }
        res.push_back(index + 1);
        index = fm[index];
    }

    // 反转并输出结果
    reverse(res.begin(), res.end());
    for (int r : res) {
        cout << r << " ";
    }

    return 0;
}

Java:[此代码未进行大量数据的测试,仅供参考]

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // 读取输入
        int N = scanner.nextInt();
        int[] task = new int[N];
        for (int i = 0; i < N; i++) {
            task[i] = scanner.nextInt();
        }
        int M = scanner.nextInt();
        
        // 初始化 dp 数组
        final int INF = Intege

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

2024 BAT笔试合集 文章被收录于专栏

持续收录字节、腾讯、阿里、美团、美团、拼多多、华为等笔试题解,包含python、C++、Java多种语言版本,持续更新中。

全部评论
第一题的参考题解怎么看不到呀?
点赞 回复 分享
发布于 08-12 19:33 山西
请问用友笔试支持本地IDE吗,看考试须知上没有说明
点赞 回复 分享
发布于 08-13 15:47 山东

相关推荐

11-02 12:58
已编辑
西安电子科技大学 C++
美团 软件开发移动端/web前端 (x5)*15.5
点赞 评论 收藏
分享
6 8 评论
分享
牛客网
牛客企业服务