用友笔试 用友笔试题 0819

笔试时间:2025年8月19日

往年笔试合集:

2023春招秋招笔试合集

2024春招秋招笔试合集

第一题

某电商平台要搞营销活动,对一批优质用户发放优惠券,每个用户只能领1张。平台对用户的账号进行了ID映射,用户id从0开始自增。比如:第一个用户A的ID为0,第二个用户B的ID为1,第三个是2,...…第n个是n-1。相邻的用户不能同时领到优惠券。假设给定一个整数数组,由若干0和1组成,其中 0表示未领取优惠券,1表示领取了优惠券。另有一个数n,判断能否在遵循领取规则的情况下再发放 n张优惠券?能返回 true,不能返回 false。

输入描述

输入两个参数: 1、一个int的一维数组coupons,该数组由0,1组成,0表示未领取优惠券,1表示领取了优惠券; 2、准备再发放优惠券的张数n

输出描述

输出为布尔值,如果能发放n张优惠券,则返回true,否则返回false。

样例输入

1,0,0,0,1

1

样例输出

true

参考题解

该代码采用贪心策略来解决问题。核心思路是:遍历一遍用户列表(数组),只要遇到一个可以发放优惠券的位置,就立即发放一张。一个位置可以发放优惠券的判断条件是:该用户当前没有优惠券(值为0)。其左边相邻的用户没有优惠券(或者该用户是第一个用户)。其右边相邻的用户没有优惠券(或者该用户是最后一个用户)。在遍历过程中,每成功发放一张,就更新该位置的状态并进行计数。遍历完成后,比较成功发放的总数是否大于或等于需要发放的数量 n,从而得出最终结果。

C++:

#include <bits/stdc++.h>
using namespace std;

bool canPlaceMoreCoupons(vector<int>& coupons, int n) {
    if (n <= 0) return true;
    int count = 0, len = (int)coupons.size();
    for (int i = 0; i < len; ++i) {
        if (coupons[i] == 0) {
            bool leftOk = (i == 0) || (coupons[i - 1] == 0);
            bool rightOk = (i == len - 1) || (coupons[i + 1] == 0);
            if (leftOk && rightOk) {
                coupons[i] = 1;
                ++count;
            }
        }
    }
    return count >= n;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    string line;
    if (!getline(cin, line)) return 0;   // 第一行: 逗号分隔的数组
    int n; cin >> n;                     // 第二行: 整数 n

    vector<int> coupons;
    {
        stringstream ss(line);
        string part;
        while (getline(ss, part, ',')) {
            if (!part.empty()) coupons.push_back(stoi(part));
            else coupons.push_back(0); // 若出现空片段,按 0 处理(与 Java 的 Integer.parseInt 不同,通常无空片段)
        }
    }

    bool ok = canPlaceMoreCoupons(coupons, n);
    cout << (ok ? "true" : "false") << "\n";
    return 0;
}

Java:

import java.util.Scanner;

public class Main {
   public static void main(String[] args) {
       Scanner sc = new Scanner(System.in);
       String line = sc.nextLine();
       int n = sc.nextInt();
       sc.close();

       String[] parts = line.split(",");
       int[] coupons = new int[parts.length];
       for (int i = 0; i < parts.length; i++) {
           coupons[i] = Integer.parseInt(parts[i]);
       }

       System.out.println(canPlaceMoreCoupons(coupons, n));
   }

   public static boolean canPlaceMoreCoupons(int[] coupons, int n) {
       if (n <= 0) {
           return true;
       }

       int count = 0;
       int len = coupons.length;

       for (int i = 0; i < len; i++) {
           if (coupons[i] == 0) {
               boolean leftOk = (i == 0) || (coupons[i - 1] == 0);
               boolean rightOk = (i == len - 1) || (coupons[i + 1] == 0);

               if (leftOk && rightOk) {
                   coupons[i] = 1;
                   count++;
               }
           }
       }

       return count >= n;
   }
}

Python:

import sys

def can_place_more_coupons(coupons, n):
    if n <= 0:
        return True
    count = 0
    length = len(coupons)
    for i in range(length):
        if coupons[i] == 0:
            left_ok = (i == 0) or (coupons[i - 1] == 0)
            right_ok = (i == length - 1) or (coupons[i + 1] == 0)
            if left_ok and right_ok:
                coupons[i] = 1
                count += 1
    return count >= n

def main():
    line = sys.stdin.readline().strip()   # 第一行: 逗号分隔的数组
    n_line = sys.stdin.readline().strip() # 第二行: 整数 n
    n = int(n_line)

    parts = line.split(",")
    coupons = [int(p) for p in parts if p != ""]  # 简单处理空片段
    res = can_place_more_coupons(coupons, n)
    # 与 Java 输出一致(小写)
    print("true" if res else "false")

if __name__ == "__main__":
    main()

第二题

小友产业园中有一个电动汽车充电站,充电站中有 k 个充电桩,编号从 1 ~ k。

现在有一个长度为n的二维数组,其中第 i 个元素为[arrivalTime, chargingTime],表示第 i 辆车在时间 arrivalTime 到达充电站需要充电 chargingTime小时。

调度规则:先到先服务: 按到达时间顺序安排充电充电桩分配: 优先使用编号最小的空闲充电桩等待机制: 如果所有充电桩都被占用,车辆需要排队等待同时到达: 如果多辆车同时到达,按车辆编号(输入顺序)优先请你模拟出该充电站的充电桩调度过程。按车辆编号顺序,每行输出一辆车的充电信息,格式为:

车辆编号 开始充电时间 结束充电时间 充电桩编号

输入描述

第一行2个整数n和k,含义如题干所述。

接下来n行,每行2个整数arrivalTime和chargingTime,含义如题干所述。200>=k>=1200>=n>=1arrivalTime>=010>=chargingTime>=1

输出描述

输出n行,每行4个整数,分别表示车辆编号,开始充电时间,结束充电时间,充电桩编号。

样例输入

4 2

0 5

1 1

2 2

6 3

样例输出

0 0 5 1

1 1 2 2

2 2 4 2

3 6 9 1

说明:时间0: 车0到达,用桩1(0-5)时间1: 车1到达,用桩2(1-2)时间2: 车2到达,车1完成,车2用桩2(2-4)时间4: 车2完成时间5: 车0完成时间6: 车3到达,用桩1(6-9)

参考题解

数据结构:创建一个 Car 类来存储每辆车的所有信息,包括其原始编号(ID)、到达时间、充电时长,以及后续计算出的开始充电时间、结束充电时间、和使用的充电桩编号。确定处理顺序:将所有车辆信息读入一个 Car 对象列表。对这个列表进行排序。排序规则完全遵循题目的调度优先级:首先按到达时间升序,如果到达时间相同,则按车辆原始编号升序。这样排序后,列表中的车辆顺序就是它们被处理的先后顺序。模拟调度过程:对于当前车辆,遍历所有充电桩(从1到k)。计算该车在每个桩上可能的最早开始充电时间。这个时间点是 车辆到达时间 和 充电桩当前可用时间 中的较大值。在所有充电桩中,选择一个能提供 最早开始充电时间 的桩。如果多个桩都能提供相同的最早开始时间,由于遍历顺序是从小到大,自然会选中编号最小的那个。确定了最佳充电桩和开始时间后,计算出结束时间,并将这些结果存入当前车辆对象中。最后,更新所选充电桩的 pileFreeTime 为该车的结束充电时间,表示它在该时间点之前都处于占用状态。创建一个数组 pileFreeTime 来记录每个充电桩下一次可用的时间点,初始时所有值都为0。遍历排好序的车辆列表,为每辆车分配充电桩:格式化输出:所有车辆都处理完毕后,Car 列表中已经包含了所有结果,但列表当前是按处理顺序排列的。为了按车辆原始编号顺序输出,需要对列表再次排序,这次的排序规则仅依据车辆的原始ID。最后,遍历排序后的列表,按题目要求的格式输出每辆车的信息。

C++:

#include <bits/stdc++.h>
using namespace std;

struct Car {
    int id;
    int arrivalTime;
    int chargingTime;
    int startChargeTime = 0;
    int endChargeTime = 0;
    int pileId = 0;
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, k;
    if (!(cin >> n >> k)) return 0;

    vector<Car> cars;
    cars.reserve(n);
    for (int i = 0; i < n; ++i) {
        int at, ct;
        cin >> at >> ct;
        cars.push_back(Car{i, at, ct});
    }

    // 按到达时间、id排序
    sort(cars.begin(), cars.end(), [](const Car& a, const Car& b){
        if (a.arrivalTime != b.arrivalTime) return a.arrivalTime < b.arrivalTime;
        return a.id < b.id;
    });

    // 桩的空闲时间(1..k)
    vector<int> pileFreeTime(k + 1, 0);

    for (auto& car : cars) {
        int bestPileIndex = -1;
        int earliestStartTime = INT_MAX;
        for (int i = 1; i <= k; ++i) {
            int currentStartTime = max(car.arrivalTime, pileFreeTime[i]);
            if (currentStartTime < earliestStartTime) {
                earliestStartTime = currentStartTime;
                bestPileIndex = i;
            }
        }
        car.startChargeTime = earliestStartTime;
        car.endChargeTime = car.startChargeTime + car.chargingTime;
        car.pileId = bestPileIndex;
        pileFreeTime[bestPileIndex] = car.endChargeTime;
    }

    // 按id输出
    sort(cars.begin(), cars.end(), [](const Car& a, const Car& b){
        return a.id < b.id;
    });

    for (const auto& car : cars) {
        cout << car.id << ' ' << car.startChargeTime << ' ' << car.endChargeTime << ' ' << car.pileId << '\n';
    }
    return 0;
}

Java:

import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Main {

   static class Car {
       int id;
       int arrivalTime;
       int chargingTime;
       int startChargeTime;
       int endChargeTime;
       int pileId;

       public Car(int id, int arrivalTime, int chargingTime) {
           this.id = id;
           this.arrivalTime = arrivalTime;
           this.chargingTime = chargingTime;
       }
   }

   public static void main(String[] args) {
       Scanner sc = new Scanner(System.in);
       int n = sc.nextInt();
       int k = sc.nextInt();

       List<Car> cars = new ArrayList<>();
       for (int i = 0; i < n; i++) {
           cars.add(new Car(i, sc.nextInt(), sc.nextInt()));
       }

       Collections.sort(cars, new Comparator<Car>() {
           @Override
           public int compare(Car c1, Car c2) {
               if (c1.arrivalTime != c2.arrivalTime) {
                   return Integer.compare(c1.arrivalTime, c2.arrivalTime);
               } else {
                   return Integer.compare(c1.id, c2.id);
               }
           }
       });

       int[] pileFreeTime = new int[k + 1];

       

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

2025 春招笔试合集 文章被收录于专栏

2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南

全部评论
做出了两道半,发面试了
点赞 回复 分享
发布于 08-26 10:30 北京
是只能用java写吗?
点赞 回复 分享
发布于 09-23 02:43 广东

相关推荐

点赞 评论 收藏
分享
真是啥人都碰上了
牛客78696106...:力工思维造就炫压抑的安卓人
点赞 评论 收藏
分享
08-15 01:16
Python
Java小萌新新萌小...:照片不用整这么大的 而且你的照片截歪了 你想找专业对口的 那普通话证写在这里其实没有什么必要 就是看着内容多点 而且里面字体大小也不一样 修改一下排版 有很多空间可以再利用一下 字大一点 不然现在这样观感不太好 再就是项目好好优化一下 加油
点赞 评论 收藏
分享
真tmd的恶心,1.面试开始先说我讲简历讲得不好,要怎样讲怎样讲,先讲背景,再讲技术,然后再讲提升多少多少,一顿说教。2.接着讲项目,我先把背景讲完,开始讲重点,面试官立即打断说讲一下重点,无语。3.接着聊到了项目的对比学习的正样本采样,说我正样本采样是错的,我解释了十几分钟,还是说我错的,我在上一家实习用这个方法能work,并经过市场的检验,并且是顶会论文的复现,再怎么不对也不可能是错的。4.面试官,说都没说面试结束就退出会议,把面试者晾在会议里面,丝毫不尊重面试者难受的点:1.一开始是讲得不好是欣然接受的,毕竟是学习。2.我按照面试官的要求,先讲背景,再讲技术。当我讲完背景再讲技术的时候(甚至已经开始蹦出了几个技术名词),凭什么打断我说讲重点,是不能听出人家重点开始了?这也能理解,每个人都有犯错,我也没放心上。3.我自己做过的项目,我了解得肯定比他多,他这样贬低我做过的项目,说我的工作是错误的,作为一个技术人员,我是完全不能接受的,因此我就和他解释,但无论怎么解释都说我错。凭什么,作为面试官自己不了解相关技术,别人用这个方式work,凭什么还认为这个方法是错的,不接受面试者的解释。4.这个无可厚非,作为面试官,不打招呼就退出会议,把面试者晾着,本身就是有问题。综上所述,我现在不觉得第一第二点也是我的问题,面试官有很大的问题,就是专门恶心人的,总结面试官说教,不尊重面试者,打击面试者,不接受好的面试者,技术一般的守旧固执分子。有这种人部门有这种人怎么发展啊。最后去查了一下,岗位关闭了。也有可能是招到人了来恶心人的,但是也很cs
牛客20646354...:招黑奴啊,算法工程师一天200?
点赞 评论 收藏
分享
评论
1
5
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务