【2024年华为OD机试】 (A卷,100分)- 总最快检测效率(Java JS PythonC/C++)
一、问题描述
题目描述
在系统、网络均正常的情况下组织核酸采样员和志愿者对人群进行核酸检测筛查。
每名采样员的效率不同,采样效率为 N
人/小时。由于外界变化,采样员的效率会以 M
人/小时为粒度发生变化,M
为采样效率浮动粒度,M = N * 10%
,输入保证 N * 10%
的结果为整数。
采样员效率浮动规则:
- 采样员需要一名志愿者协助组织才能发挥正常效率,在此基础上,每增加一名志愿者,效率提升
1M
,最多提升3M
; - 如果没有志愿者协助组织,效率下降
2M
。
怎么安排速度最快?求总最快检测效率(总检查效率为各采样人员效率值相加)。
输入描述
第一行:第一个值,采样员人数,取值范围 [1, 100]
;第二个值,志愿者人数,取值范围 [1, 500]
;
第二行:各采样员基准效率值(单位人/小时),取值范围 [60, 600]
,保证序列中每项值计算 10%
为整数。
输出描述
第一行:总最快检测效率(单位人/小时)
用例
用例 1
输入:
2 2
200 200
输出:
400
说明:
输入需要保证采样员基准效率值序列的每个值 *10%
为整数。
解题思路
-
计算每个采样员的效率浮动粒度
M
:M = N * 10%
-
确定每个采样员的最优效率:
- 每个采样员至少需要一名志愿者才能发挥正常效率
N
。 - 每增加一名志愿者,效率提升
1M
,最多提升3M
。 - 如果没有志愿者协助,效率下降
2M
。
- 每个采样员至少需要一名志愿者才能发挥正常效率
-
分配志愿者:
- 优先为每个采样员分配一名志愿者,确保每个采样员至少发挥正常效率
N
。 - 剩余的志愿者按照每个采样员效率提升的优先级进行分配,即先为效率提升空间大的采样员分配志愿者。
- 优先为每个采样员分配一名志愿者,确保每个采样员至少发挥正常效率
-
计算总最快检测效率:
- 将所有采样员的最优效率相加。
逻辑分析解法
问题背景
假设有 x
个采样员,每个采样员的正常采样效率分别为 a1, a2, a3, ..., ax
,还有 y
个志愿者。我们需要计算在最优分配志愿者的情况下,所有采样员的总最快检测效率。
初始状态
初始时,不给任何采样员分配志愿者,每个采样员的效率会下降 2M
,其中 M = N * 10%
。因此,所有采样员的初始效率为:
[ (a1 * 0.8) + (a2 * 0.8) + (a3 * 0.8) + … + (ax * 0.8) ]
收集每个采样员的新增效率数据
对于每个采样员,我们收集以下数据:
- 增加第一个志愿者,新增的效率
- 增加第二个志愿者,新增的效率
- 增加第三个志愿者,新增的效率
- 增加第四个志愿者,新增的效率
例如,对于采样员 a1
:
- 增加第一个志愿者,新增效率
a1 * 0.2
- 增加第二个志愿者,新增效率
a1 * 0.1
- 增加第三个志愿者,新增效率
a1 * 0.1
- 增加第四个志愿者,新增效率
a1 * 0.1
构建新增效率列表
我们将每个采样员的新增效率数据收集到一个列表 add
中。这个列表包含所有采样员在增加志愿者时的新增效率。
降序排序
对 add
列表进行降序排序,这样可以确保我们优先选择新增效率最高的组合。排序后的列表前 y
个元素即为最优的新增效率组合。
递进关系的保证
有人可能会疑问,对于每个采样员而言,其新增的效率是递进的,例如增加第二个志愿者的新增效率必须在增加第一个志愿者的基础上。排序后,是否还能保证这个递进关系?
答案是可以的。因为本题已经固定了新增效率的规则:
- 采样员需要一名志愿者协助组织才能发挥正常效率(即提升
2M
效率) - 在此基础上,每增加一名志愿者,效率提升
1M
因此,一个采样员想要提升 1M
效率,前面必须先提升 2M
效率。在 add
列表进行降序排序时,2M
一定会在 1M
之前。
多个采样员的新增效率混在一起排序
即使将多个采样员的新增效率混在一起排序,也不会破坏单个采样员的新增效率的递进关系。相当于有多个降序列表,例如:
[8, 4, 4, 4]
[10, 5, 5, 5]
[6, 3, 3, 3]
将这些降序列表合并后,再次降序排序:
[ [10, 8, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3] ]
这个合并后的列表依然维持着各自采样员的新增效率递进关系:
[ [10, 8, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3] ]
总结
通过上述步骤,我们可以高效地计算出总最快检测效率。具体步骤如下:
- 计算每个采样员的初始效率(没有志愿者时的效率)。
- 收集每个采样员在增加志愿者时的新增效率数据。
- 将所有新增效率数据收集到一个列表中。
- 对该列表进行降序排序。
- 选择前
y
个新增效率数据,计算总新增效率。 - 将总新增效率加到初始效率上,得到总最快检测效率。
这种方法的时间复杂度主要由排序操作决定,为 O(x * 4 * log(x * 4))
,其中 x
是采样员的数量。由于每个采样员最多有 4 个新增效率数据,因此 x * 4
是新增效率数据的总数。
二、JavaScript算法源码
以下是带有详细中文注释和逻辑讲解的 JavaScript 代码:
JavaScript 代码实现
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;void (async function () {// 读取输入:x 是采样员人数,y 是志愿者人数const [x, y] = (await readline()).split(" ").map(Number);// 读取输入:x 个采样员的正常效率const normals = (await readline()).split(" ").map(Number);// base 记录所有采样员的裸奔效率(即没有志愿者协助时的总效率)let base = 0;// add 记录每个采样员在志愿者协助下的新增效率const add = [];// 遍历每个采样员的正常效率for (let normal of normals) {// 计算采样效率浮动粒度 M = 正常效率的 10%const m = normal * 0.1;// 如果没有志愿者协助,采样员的效率下降 2M,即 8Mbase += 8 * m;// 增加第1个志愿者时,新增效率为 2M// 增加第2个志愿者时,新增效率为 M// 增加第3个志愿者时,新增效率为 M// 增加第4个志愿者时,新增效率为 Madd.push(2 * m, m, m, m);}// 对所有新增效率进行降序排序add.sort((a, b) => b - a);// 计算最高效率:裸奔效率 + 前 y 大的新增效率const ans = base + add.slice(0, y).reduce((a, b) => a + b, 0);// 输出结果console.log(ans);
})();
代码讲解
1. 输入处理
- 使用
readline
模块从标准输入读取数据。 - 读取第一行输入,获取采样员人数
x
和志愿者人数y
。 - 读取第二行输入,获取每个采样员的正常效率,并存储在数组
normals
中。
2. 计算裸奔效率 base
- 遍历每个采样员的正常效率
normal
:- 计算采样效率浮动粒度
m = normal * 0.1
。 - 如果没有志愿者协助,采样员的效率下降
2m
,即效率为8m
。 - 将
8m
累加到base
中,表示所有采样员的裸奔效率。
- 计算采样效率浮动粒度
3. 计算新增效率 add
- 对于每个采样员,计算在志愿者协助下的新增效率:
- 增加第1个志愿者时,新增效率为
2m
。 - 增加第2个志愿者时,新增效率为
m
。 - 增加第3个志愿者时,新增效率为
m
。 - 增加第4个志愿者时,新增效率为
m
。
- 增加第1个志愿者时,新增效率为
- 将所有新增效率存储在数组
add
中。
4. 排序新增效率
- 对数组
add
进行降序排序,确保优先选择新增效率最大的志愿者分配方案。
5. 计算最高效率
- 取前
y
个最大的新增效率,累加到base
中,得到最高效率ans
。 - 使用
reduce
函数对前y
个新增效率求和。
6. 输出结果
- 打印最高效率
ans
。
示例解析
输入
3 2
100 200 300
运行结果
376
- 解析:
- 采样员正常效率:
[100, 200, 300]
。 - 计算每个采样员的
m
值:- 第1个采样员:
m = 100 * 0.1 = 10
。 - 第2个采样员:
m = 200 * 0.1 = 20
。 - 第3个采样员:
m = 300 * 0.1 = 30
。
- 第1个采样员:
- 计算裸奔效率
base
:- 第1个采样员:
8 * 10 = 80
。 - 第2个采样员:
8 * 20 = 160
。 - 第3个采样员:
8 * 30 = 240
。 base = 80 + 160 + 240 = 480
。
- 第1个采样员:
- 计算新增效率
add
:- 第1个采样员:
[20, 10, 10, 10]
。 - 第2个采样员:
[40, 20, 20, 20]
。 - 第3个采样员:
[60, 30, 30, 30]
。 add = [20, 10, 10, 10, 40, 20, 20, 20, 60, 30, 30, 30]
。
- 第1个采样员:
- 对
add
降序排序:add = [60, 40, 30, 30, 30, 20, 20, 20, 10, 10, 10, 10]
。
- 取前
y = 2
个最大的新增效率:60 + 40 = 100
。
- 计算最高效率:
ans = base + 100 = 480 + 100 = 580
。
- 采样员正常效率:
总结
- 该代码通过计算裸奔效率和新增效率,结合排序和累加操作,高效地计算了最高效率。
- 时间复杂度主要取决于排序操作,为
O(n log n)
,其中n
是新增效率的数量。 - 代码逻辑清晰,注释详细,易于理解和扩展。
如果有其他问题,欢迎随时提问!
三、Java算法源码
以下是带有详细中文注释和逻辑讲解的 Java 代码:
Java 代码实现
import java.util.ArrayList;
import java.util.Scanner;public class Main {public static void main(String[] args) {// 使用 Scanner 读取输入Scanner sc = new Scanner(System.in);// 读取输入:x 是采样员人数,y 是志愿者人数int x = sc.nextInt();int y = sc.nextInt();// 读取输入:x 个采样员的正常效率int[] normals = new int[x];for (int i = 0; i < x; i++) {normals[i] = sc.nextInt();}// base 记录所有采样员的裸奔效率(即没有志愿者协助时的总效率)int base = 0;// increase 记录每个采样员在志愿者协助下的新增效率ArrayList<Integer> increase = new ArrayList<>();// 遍历每个采样员的正常效率for (int normal : normals) {// 计算采样效率浮动粒度 M = 正常效率的 10%int m = normal / 10;// 如果没有志愿者协助,采样员的效率下降 2M,即 8Mbase += 8 * m;// 增加第1个志愿者时,新增效率为 2Mincrease.add(2 * m);// 增加第2个志愿者时,新增效率为 Mincrease.add(m);// 增加第3个志愿者时,新增效率为 Mincrease.add(m);// 增加第4个志愿者时,新增效率为 Mincrease.add(m);}// 对所有新增效率进行降序排序increase.sort((a, b) -> b - a);// 计算最高效率:裸奔效率 + 前 y 大的新增效率int ans =base+ increase.subList(0, Math.min(y, increase.size())) // 取前 y 个新增效率.stream() // 转换为流.reduce(Integer::sum) // 求和.orElse(0); // 如果流为空,返回 0// 输出结果System.out.println(ans);}
}
代码讲解
1. 输入处理
- 使用
Scanner
从标准输入读取数据。 - 读取第一行输入,获取采样员人数
x
和志愿者人数y
。 - 读取第二行输入,获取每个采样员的正常效率,并存储在数组
normals
中。
2. 计算裸奔效率 base
- 遍历每个采样员的正常效率
normal
:- 计算采样效率浮动粒度
m = normal / 10
。 - 如果没有志愿者协助,采样员的效率下降
2m
,即效率为8m
。 - 将
8m
累加到base
中,表示所有采样员的裸奔效率。
- 计算采样效率浮动粒度
3. 计算新增效率 increase
- 对于每个采样员,计算在志愿者协助下的新增效率:
- 增加第1个志愿者时,新增效率为
2m
。 - 增加第2个志愿者时,新增效率为
m
。 - 增加第3个志愿者时,新增效率为
m
。 - 增加第4个志愿者时,新增效率为
m
。
- 增加第1个志愿者时,新增效率为
- 将所有新增效率存储在
ArrayList<Integer> increase
中。
4. 排序新增效率
- 对
increase
进行降序排序,确保优先选择新增效率最大的志愿者分配方案。
5. 计算最高效率
- 取前
y
个最大的新增效率:- 使用
subList(0, Math.min(y, increase.size()))
确保不会越界。
- 使用
- 使用
stream().reduce(Integer::sum)
对前y
个新增效率求和。 - 如果流为空(即
y = 0
),返回0
。
6. 输出结果
- 打印最高效率
ans
。
示例解析
输入
3 2
100 200 300
运行结果
580
- 解析:
- 采样员正常效率:
[100, 200, 300]
。 - 计算每个采样员的
m
值:- 第1个采样员:
m = 100 / 10 = 10
。 - 第2个采样员:
m = 200 / 10 = 20
。 - 第3个采样员:
m = 300 / 10 = 30
。
- 第1个采样员:
- 计算裸奔效率
base
:- 第1个采样员:
8 * 10 = 80
。 - 第2个采样员:
8 * 20 = 160
。 - 第3个采样员:
8 * 30 = 240
。 base = 80 + 160 + 240 = 480
。
- 第1个采样员:
- 计算新增效率
increase
:- 第1个采样员:
[20, 10, 10, 10]
。 - 第2个采样员:
[40, 20, 20, 20]
。 - 第3个采样员:
[60, 30, 30, 30]
。 increase = [20, 10, 10, 10, 40, 20, 20, 20, 60, 30, 30, 30]
。
- 第1个采样员:
- 对
increase
降序排序:increase = [60, 40, 30, 30, 30, 20, 20, 20, 10, 10, 10, 10]
。
- 取前
y = 2
个最大的新增效率:60 + 40 = 100
。
- 计算最高效率:
ans = base + 100 = 480 + 100 = 580
。
- 采样员正常效率:
总结
- 该代码通过计算裸奔效率和新增效率,结合排序和累加操作,高效地计算了最高效率。
- 时间复杂度主要取决于排序操作,为
O(n log n)
,其中n
是新增效率的数量。 - 代码逻辑清晰,注释详细,易于理解和扩展。
如果有其他问题,欢迎随时提问!
四、Python算法源码
以下是带有详细中文注释和逻辑讲解的 Python 代码:
Python 代码实现
# 输入获取
x, y = map(int, input().split()) # x是采样员人数,y是志愿者人数
normals = list(map(int, input().split())) # x个采样员的正常效率# 算法入口
def getResult():# base 记录所有采样员的裸奔效率(即没有志愿者协助时的总效率)base = 0# increase 记录每个采样员在志愿者协助下的新增效率increase = []# 遍历每个采样员的正常效率for normal in normals:# 计算采样效率浮动粒度 M = 正常效率的 10%m = normal // 10# 如果没有志愿者协助,采样员的效率下降 2M,即 8Mbase += 8 * m# 增加第1个志愿者时,新增效率为 2Mincrease.append(2 * m)# 增加第2个志愿者时,新增效率为 Mincrease.append(m)# 增加第3个志愿者时,新增效率为 Mincrease.append(m)# 增加第4个志愿者时,新增效率为 Mincrease.append(m)# 对所有新增效率进行降序排序increase.sort(reverse=True)# 计算最高效率:裸奔效率 + 前 y 大的新增效率return base + sum(increase[:y])# 算法调用
print(getResult())
代码讲解
1. 输入处理
- 使用
input().split()
从标准输入读取数据。 - 读取第一行输入,获取采样员人数
x
和志愿者人数y
。 - 读取第二行输入,获取每个采样员的正常效率,并存储在列表
normals
中。
2. 计算裸奔效率 base
- 遍历每个采样员的正常效率
normal
:- 计算采样效率浮动粒度
m = normal // 10
。 - 如果没有志愿者协助,采样员的效率下降
2m
,即效率为8m
。 - 将
8m
累加到base
中,表示所有采样员的裸奔效率。
- 计算采样效率浮动粒度
3. 计算新增效率 increase
- 对于每个采样员,计算在志愿者协助下的新增效率:
- 增加第1个志愿者时,新增效率为
2m
。 - 增加第2个志愿者时,新增效率为
m
。 - 增加第3个志愿者时,新增效率为
m
。 - 增加第4个志愿者时,新增效率为
m
。
- 增加第1个志愿者时,新增效率为
- 将所有新增效率存储在列表
increase
中。
4. 排序新增效率
- 对
increase
进行降序排序,确保优先选择新增效率最大的志愿者分配方案。
5. 计算最高效率
- 取前
y
个最大的新增效率:- 使用切片
increase[:y]
获取前y
个元素。
- 使用切片
- 使用
sum()
函数对前y
个新增效率求和。 - 将裸奔效率
base
与新增效率之和相加,得到最高效率。
6. 输出结果
- 调用
getResult()
函数并打印结果。
示例解析
输入
3 2
100 200 300
运行结果
580
- 解析:
- 采样员正常效率:
[100, 200, 300]
。 - 计算每个采样员的
m
值:- 第1个采样员:
m = 100 // 10 = 10
。 - 第2个采样员:
m = 200 // 10 = 20
。 - 第3个采样员:
m = 300 // 10 = 30
。
- 第1个采样员:
- 计算裸奔效率
base
:- 第1个采样员:
8 * 10 = 80
。 - 第2个采样员:
8 * 20 = 160
。 - 第3个采样员:
8 * 30 = 240
。 base = 80 + 160 + 240 = 480
。
- 第1个采样员:
- 计算新增效率
increase
:- 第1个采样员:
[20, 10, 10, 10]
。 - 第2个采样员:
[40, 20, 20, 20]
。 - 第3个采样员:
[60, 30, 30, 30]
。 increase = [20, 10, 10, 10, 40, 20, 20, 20, 60, 30, 30, 30]
。
- 第1个采样员:
- 对
increase
降序排序:increase = [60, 40, 30, 30, 30, 20, 20, 20, 10, 10, 10, 10]
。
- 取前
y = 2
个最大的新增效率:60 + 40 = 100
。
- 计算最高效率:
ans = base + 100 = 480 + 100 = 580
。
- 采样员正常效率:
总结
- 该代码通过计算裸奔效率和新增效率,结合排序和累加操作,高效地计算了最高效率。
- 时间复杂度主要取决于排序操作,为
O(n log n)
,其中n
是新增效率的数量。 - 代码逻辑清晰,注释详细,易于理解和扩展。
如果有其他问题,欢迎随时提问!
五、C/C++算法源码:
以下是 C++ 实现,并附带详细的中文注释和逻辑讲解:
C++ 代码实现
#include <iostream>
#include <vector>
#include <algorithm> // 用于排序
using namespace std;// 算法入口
int getResult(int x, int y, vector<int>& normals) {// base 记录所有采样员的裸奔效率(即没有志愿者协助时的总效率)int base = 0;// increase 记录每个采样员在志愿者协助下的新增效率vector<int> increase;// 遍历每个采样员的正常效率for (int normal : normals) {// 计算采样效率浮动粒度 M = 正常效率的 10%int m = normal / 10;// 如果没有志愿者协助,采样员的效率下降 2M,即 8Mbase += 8 * m;// 增加第1个志愿者时,新增效率为 2Mincrease.push_back(2 * m);// 增加第2个志愿者时,新增效率为 Mincrease.push_back(m);// 增加第3个志愿者时,新增效率为 Mincrease.push_back(m);// 增加第4个志愿者时,新增效率为 Mincrease.push_back(m);}// 对所有新增效率进行降序排序sort(increase.begin(), increase.end(), greater<int>());// 计算最高效率:裸奔效率 + 前 y 大的新增效率int sumIncrease = 0;for (int i = 0; i < y && i < increase.size(); i++) {sumIncrease += increase[i];}return base + sumIncrease;
}int main() {// 输入获取int x, y;cin >> x >> y; // x是采样员人数,y是志愿者人数vector<int> normals(x);for (int i = 0; i < x; i++) {cin >> normals[i]; // 读取x个采样员的正常效率}// 算法调用int result = getResult(x, y, normals);// 输出结果cout << result << endl;return 0;
}
代码讲解
1. 输入处理
- 使用
cin
从标准输入读取数据。 - 读取第一行输入,获取采样员人数
x
和志愿者人数y
。 - 读取第二行输入,获取每个采样员的正常效率,并存储在
vector<int> normals
中。
2. 计算裸奔效率 base
- 遍历每个采样员的正常效率
normal
:- 计算采样效率浮动粒度
m = normal / 10
。 - 如果没有志愿者协助,采样员的效率下降
2m
,即效率为8m
。 - 将
8m
累加到base
中,表示所有采样员的裸奔效率。
- 计算采样效率浮动粒度
3. 计算新增效率 increase
- 对于每个采样员,计算在志愿者协助下的新增效率:
- 增加第1个志愿者时,新增效率为
2m
。 - 增加第2个志愿者时,新增效率为
m
。 - 增加第3个志愿者时,新增效率为
m
。 - 增加第4个志愿者时,新增效率为
m
。
- 增加第1个志愿者时,新增效率为
- 将所有新增效率存储在
vector<int> increase
中。
4. 排序新增效率
- 使用
sort()
函数对increase
进行降序排序,确保优先选择新增效率最大的志愿者分配方案。greater<int>()
是降序排序的比较函数。
5. 计算最高效率
- 取前
y
个最大的新增效率:- 使用循环遍历前
y
个元素,并累加它们的值。
- 使用循环遍历前
- 将裸奔效率
base
与新增效率之和相加,得到最高效率。
6. 输出结果
- 调用
getResult()
函数并打印结果。
示例解析
输入
3 2
100 200 300
运行结果
580
- 解析:
- 采样员正常效率:
[100, 200, 300]
。 - 计算每个采样员的
m
值:- 第1个采样员:
m = 100 / 10 = 10
。 - 第2个采样员:
m = 200 / 10 = 20
。 - 第3个采样员:
m = 300 / 10 = 30
。
- 第1个采样员:
- 计算裸奔效率
base
:- 第1个采样员:
8 * 10 = 80
。 - 第2个采样员:
8 * 20 = 160
。 - 第3个采样员:
8 * 30 = 240
。 base = 80 + 160 + 240 = 480
。
- 第1个采样员:
- 计算新增效率
increase
:- 第1个采样员:
[20, 10, 10, 10]
。 - 第2个采样员:
[40, 20, 20, 20]
。 - 第3个采样员:
[60, 30, 30, 30]
。 increase = [20, 10, 10, 10, 40, 20, 20, 20, 60, 30, 30, 30]
。
- 第1个采样员:
- 对
increase
降序排序:increase = [60, 40, 30, 30, 30, 20, 20, 20, 10, 10, 10, 10]
。
- 取前
y = 2
个最大的新增效率:60 + 40 = 100
。
- 计算最高效率:
ans = base + 100 = 480 + 100 = 580
。
- 采样员正常效率:
总结
- 该代码通过计算裸奔效率和新增效率,结合排序和累加操作,高效地计算了最高效率。
- 时间复杂度主要取决于排序操作,为
O(n log n)
,其中n
是新增效率的数量。 - 代码逻辑清晰,注释详细,易于理解和扩展。
如果有其他问题,欢迎随时提问!
六、贪心思维解法
解题思路详细分析
问题背景
给定 x
个采样员和 y
个志愿者,每个采样员有一个基准效率 N
,采样员的效率会根据志愿者的数量变化。具体规则如下:
- 每个采样员需要至少一个志愿者才能发挥正常效率
N
。 - 每增加一个志愿者,效率提升
10%
,最多提升30%
。 - 如果没有志愿者,效率下降
20%
。
目标是最大化总检测效率。
解题思路
情况 1:志愿者数量少于采样员 (y < x
)
-
初始分配:
- 将志愿者优先分配给效率最高的采样员,每个采样员分配一个志愿者。
- 如果志愿者数量不足以分配给所有采样员,部分采样员将没有志愿者,效率下降
20%
。
-
优化分配:
- 计算每个采样员在增加一个志愿者时的效率提升。
- 从效率提升最大的采样员开始,逐步分配剩余的志愿者,直到没有剩余志愿者或所有采样员都已分配到志愿者。
- 如果高效率的采样员已经提升
30%
,则考虑下一个高效率的采样员。
情况 2:志愿者数量不少于采样员 (y >= x
)
-
初始分配:
- 每个采样员分配一个志愿者,确保所有采样员都能发挥正常效率
N
。 - 计算剩余的志愿者数量
y - x
。
- 每个采样员分配一个志愿者,确保所有采样员都能发挥正常效率
-
优化分配:
- 优先将剩余的志愿者分配给效率最高的采样员,每个采样员最多增加
3
个志愿者。 - 如果剩余的志愿者数量超过
3x
,则超出部分的志愿者没有效率提升作用,可以忽略。 - 计算每个采样员在增加一个志愿者时的效率提升。
- 从效率提升最大的采样员开始,逐步分配剩余的志愿者,直到没有剩余志愿者或所有采样员都已提升
30%
。
- 优先将剩余的志愿者分配给效率最高的采样员,每个采样员最多增加
-
进一步优化:
- 如果还有剩余志愿者,考虑剥夺低效率采样员的志愿者,分配给高效率的采样员。
- 只要高效率采样员增加的
10%
效率可以大于低效率采样员减少的20%
效率,就进行调整。
详细步骤
-
计算每个采样员的初始效率:
- 没有志愿者时,效率为
N * 0.8
。 - 有一个志愿者时,效率为
N
。
- 没有志愿者时,效率为
-
收集每个采样员的新增效率数据:
- 增加第一个志愿者,新增效率
N * 0.2
。 - 增加第二个志愿者,新增效率
N * 0.1
。 - 增加第三个志愿者,新增效率
N * 0.1
。 - 增加第四个志愿者,新增效率
N * 0.1
。
- 增加第一个志愿者,新增效率
-
构建新增效率列表:
- 将每个采样员的新增效率数据收集到一个列表
add
中。
- 将每个采样员的新增效率数据收集到一个列表
-
降序排序:
- 对
add
列表进行降序排序,确保优先选择新增效率最高的组合。
- 对
-
分配志愿者:
- 情况 1:志愿者数量少于采样员
- 优先分配给效率最高的采样员,确保每个采样员至少有一个志愿者。
- 逐步分配剩余志愿者,直到没有剩余志愿者或所有采样员都已分配到志愿者。
- 情况 2:志愿者数量不少于采样员
- 每个采样员分配一个志愿者,确保所有采样员都能发挥正常效率。
- 优先将剩余的志愿者分配给效率最高的采样员,每个采样员最多增加
3
个志愿者。 - 如果还有剩余志愿者,考虑剥夺低效率采样员的志愿者,分配给高效率的采样员。
- 情况 1:志愿者数量少于采样员
-
计算总效率:
- 将所有采样员的最终效率相加,得到总最快检测效率。
通过上述步骤,我们可以高效地计算出总最快检测效率,确保在不同情况下都能找到最优的志愿者分配方案。
以下是 JavaScript、Java 和 Python 三种语言的代码实现,附带详细的中文注释和逻辑讲解。这些代码的核心逻辑是相同的,只是语言语法不同。
JavaScript 代码
代码实现
const readline = require("readline");const rl = readline.createInterface({input: process.stdin,output: process.stdout,
});const lines = [];
rl.on("line", (line) => {lines.push(line);if (lines.length === 2) {const [x, y] = lines[0].split(" ").map(Number); // 采样员人数 x,志愿者人数 yconst arrX = lines[1].split(" ").map(Number); // 每个采样员的正常效率console.log(getResult(arrX, x, y)); // 调用算法并输出结果lines.length = 0; // 清空输入缓存}
});/*** 计算最高效率* @param {number[]} arr 每个采样员的正常效率* @param {number} x 采样员人数* @param {number} y 志愿者人数* @returns {number} 最高效率*/
function getResult(arr, x, y) {// 按照正常效率降序排序arr.sort((a, b) => b - a);let max = 0; // 记录最高效率let count = 0; // 记录当前采样员已经分配的额外志愿者数量let i, j; // 双指针,i 指向高效率采样员,j 指向低效率采样员// 如果志愿者少于采样员if (y < x) {// 0~y-1 范围内的高效率采样员优先获得一个志愿者,保持正常效率// y~x-1 范围内的低效率采样员没有志愿者,效率下降 20%for (let k = 0; k < x; k++) {max += k < y ? arr[k] : arr[k] * 0.8;}i = 0; // 指向高效率采样员j = y - 1; // 指向低效率采样员}// 如果志愿者不少于采样员else {// 如果志愿者人数超过采样员四倍,则多出来的志愿者无效if (y >= 4 * x) {y = 4 * x;}// 每个采样员都默认分配一个志愿者,发挥正常效率max = arr.reduce((p, c) => p + c, 0);// surplus 记录多出来的志愿者数量let surplus = y - x;i = 0; // 指向高效率采样员j = x - 1; // 指向低效率采样员// 优先将多出来的志愿者分配给高效率的采样员while (surplus > 0) {max += arr[i] * 0.1; // 每个额外志愿者提升 10% 效率surplus--;if (++count === 3) {count = 0; // 每个采样员最多分配 3 个额外志愿者i++;}}}// 多出来的志愿者分配完后,继续考虑剥夺低效率采样员的志愿者给高效率的采样员while (i < j) {// 如果最高效率采样员提升 10% 的效率 > 最低效率采样员下降 20% 的效率if (arr[i] * 0.1 > arr[j] * 0.2) {max += arr[i] * 0.1 - arr[j] * 0.2; // 更新最高效率if (++count === 3) {count = 0; // 每个采样员最多分配 3 个额外志愿者i++;}j--;} else {break; // 如果不值得剥夺,则退出循环}}return Math.floor(max); // 返回最高效率(取整)
}
Java 代码
代码实现
import java.util.Arrays;
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int x = sc.nextInt(); // 采样员人数int y = sc.nextInt(); // 志愿者人数Integer[] arrX = new Integer[x];for (int i = 0; i < x; i++) {arrX[i] = sc.nextInt(); // 每个采样员的正常效率}System.out.println(getResult(arrX, x, y)); // 调用算法并输出结果}/*** 计算最高效率* @param arr 每个采样员的正常效率* @param x 采样员人数* @param y 志愿者人数* @return 最高效率*/public static int getResult(Integer[] arr, int x, int y) {// 按照正常效率降序排序Arrays.sort(arr, (a, b) -> b - a);int max = 0; // 记录最高效率int count = 0; // 记录当前采样员已经分配的额外志愿者数量int i, j; // 双指针,i 指向高效率采样员,j 指向低效率采样员// 如果志愿者少于采样员if (y < x) {// 0~y-1 范围内的高效率采样员优先获得一个志愿者,保持正常效率// y~x-1 范围内的低效率采样员没有志愿者,效率下降 20%for (int k = 0; k < x; k++) {max += k < y ? arr[k] : (int) (arr[k] * 0.8);}i = 0; // 指向高效率采样员j = y - 1; // 指向低效率采样员}// 如果志愿者不少于采样员else {// 如果志愿者人数超过采样员四倍,则多出来的志愿者无效if (y >= 4 * x) {y = 4 * x;}// 每个采样员都默认分配一个志愿者,发挥正常效率for (Integer val : arr) {max += val;}// surplus 记录多出来的志愿者数量int surplus = y - x;i = 0; // 指向高效率采样员j = x - 1; // 指向低效率采样员// 优先将多出来的志愿者分配给高效率的采样员while (surplus > 0) {max += arr[i] * 0.1; // 每个额外志愿者提升 10% 效率surplus--;if (++count == 3) {count = 0; // 每个采样员最多分配 3 个额外志愿者i++;}}}// 多出来的志愿者分配完后,继续考虑剥夺低效率采样员的志愿者给高效率的采样员while (i < j) {// 如果最高效率采样员提升 10% 的效率 > 最低效率采样员下降 20% 的效率if (arr[i] * 0.1 > arr[j] * 0.2) {max += arr[i] * 0.1 - arr[j] * 0.2; // 更新最高效率if (++count == 3) {count = 0; // 每个采样员最多分配 3 个额外志愿者i++;}j--;} else {break; // 如果不值得剥夺,则退出循环}}return max; // 返回最高效率}
}
Python 代码
代码实现
# 输入获取
x, y = map(int, input().split()) # 采样员人数 x,志愿者人数 y
arr = list(map(int, input().split())) # 每个采样员的正常效率# 算法入口
def getResult(arr, x, y):# 按照正常效率降序排序arr.sort(reverse=True)maxV = 0 # 记录最高效率count = 0 # 记录当前采样员已经分配的额外志愿者数量i, j = None, None # 双指针,i 指向高效率采样员,j 指向低效率采样员# 如果志愿者少于采样员if y < x:# 0~y-1 范围内的高效率采样员优先获得一个志愿者,保持正常效率# y~x-1 范围内的低效率采样员没有志愿者,效率下降 20%for k in range(x):maxV += arr[k] if k < y else int(arr[k] * 0.8)i = 0 # 指向高效率采样员j = y - 1 # 指向低效率采样员# 如果志愿者不少于采样员else:# 如果志愿者人数超过采样员四倍,则多出来的志愿者无效if y >= 4 * x:y = 4 * x# 每个采样员都默认分配一个志愿者,发挥正常效率maxV = sum(arr)# surplus 记录多出来的志愿者数量surplus = y - xi = 0 # 指向高效率采样员j = x - 1 # 指向低效率采样员# 优先将多出来的志愿者分配给高效率的采样员while surplus > 0:maxV += arr[i] * 0.1 # 每个额外志愿者提升 10% 效率surplus -= 1count += 1if count == 3:count = 0 # 每个采样员最多分配 3 个额外志愿者i += 1# 多出来的志愿者分配完后,继续考虑剥夺低效率采样员的志愿者给高效率的采样员while i < j:# 如果最高效率采样员提升 10% 的效率 > 最低效率采样员下降 20% 的效率if arr[i] * 0.1 > arr[j] * 0.2:maxV += arr[i] * 0.1 - arr[j] * 0.2 # 更新最高效率count += 1if count == 3:count = 0 # 每个采样员最多分配 3 个额外志愿者i += 1j -= 1else:break # 如果不值得剥夺,则退出循环return int(maxV) # 返回最高效率(取整)# 算法调用
print(getResult(arr, x, y))
总结
- 核心逻辑:
- 将采样员按正常效率降序排序。
- 根据志愿者数量是否足够,分配志愿者并计算效率。
- 如果志愿者不足,优先分配给高效率采样员。
- 如果志愿者有剩余,优先分配给高效率采样员,并考虑剥夺低效率采样员的志愿者。
- 时间复杂度:主要取决于排序操作,为
O(n log n)
。 - 空间复杂度:
O(n)
,用于存储采样员效率。
七、优先队列解法
优先队列解法详细分析
问题背景
给定 x
个采样员和 y
个志愿者,每个采样员有一个基准效率 N
,采样员的效率会根据志愿者的数量变化。具体规则如下:
- 每个采样员需要至少一个志愿者才能发挥正常效率
N
。 - 每增加一个志愿者,效率提升
10%
,最多提升30%
。 - 如果没有志愿者,效率下降
20%
。
目标是最大化总检测效率。
优先队列解法
-
初始化优先队列:
- 使用一个大顶堆(优先队列)来存储所有采样员。
- 每个采样员的优先级是:该采样员新增一名志愿者所能提升的效率。
- 初始时,所有采样员都没有志愿者,因此每个采样员新增一名志愿者时的效率提升为
base * 0.2
。
-
初始状态:
- 每个采样员的当前效率为
base * 0.8
。 - 每个采样员的志愿者数量为
0
。
- 每个采样员的当前效率为
-
分配志愿者:
- 从优先队列中取出优先级最高的采样员(即新增一名志愿者提升效率最多的采样员)。
- 为该采样员新增一名志愿者:
- 如果该采样员已有志愿者数量为
0
,则新增一名志愿者后,恢复为base
效率。 - 如果该采样员已有志愿者数量
<= 3
,则新增一名志愿者后,其总效率增加base * 0.1
。 - 如果该采样员已有志愿者数量
> 3
,则再新增一名志愿者不会带来效率提升,即新增效率为0
。
- 如果该采样员已有志愿者数量为
-
更新优先队列:
- 更新该采样员的志愿者数量和总效率。
- 将该采样员重新压入优先队列,进行排序。
-
结束条件:
- 当志愿者用完时,结束操作。
- 当所有采样员都安排了
4
名志愿者时,结束操作。
-
计算总效率:
- 从优先队列中取出所有采样员,累加他们的总效率,得到总最快检测效率。
详细步骤
-
初始化:
- 创建一个大顶堆(优先队列)。
- 将所有采样员的初始状态(当前效率、基准效率、志愿者数量)加入优先队列。
- 每个采样员的优先级为
base * 0.2
。
-
分配志愿者:
- 当还有志愿者可用时,执行以下操作:
- 从优先队列中取出优先级最高的采样员。
- 为该采样员新增一名志愿者:
- 如果该采样员已有志愿者数量为
0
,则当前效率更新为base
。 - 如果该采样员已有志愿者数量
<= 3
,则当前效率增加base * 0.1
。 - 如果该采样员已有志愿者数量
> 3
,则当前效率不变。
- 如果该采样员已有志愿者数量为
- 更新该采样员的志愿者数量。
- 计算该采样员新增一名志愿者后的效率提升:
- 如果该采样员已有志愿者数量
< 4
,则效率提升为base * 0.1
。 - 如果该采样员已有志愿者数量
>= 4
,则效率提升为0
。
- 如果该采样员已有志愿者数量
- 将该采样员重新压入优先队列。
- 当还有志愿者可用时,执行以下操作:
-
结束条件:
- 当志愿者用完时,结束操作。
- 当所有采样员都安排了
4
名志愿者时,结束操作。
-
计算总效率:
- 从优先队列中取出所有采样员,累加他们的当前效率,得到总最快检测效率。
通过上述步骤,我们可以高效地计算出总最快检测效率,确保在不同情况下都能找到最优的志愿者分配方案。这种方法的时间复杂度主要由优先队列的操作决定,为 O(y * log(x))
,其中 y
是志愿者的数量,x
是采样员的数量。
以下是 JavaScript、Java 和 Python 三种语言的代码实现,附带详细的中文注释和逻辑讲解。这些代码的核心逻辑是相同的,只是语言语法不同。
JavaScript 代码
代码实现
const readline = require("readline");const rl = readline.createInterface({input: process.stdin,output: process.stdout,
});const lines = [];
rl.on("line", (line) => {lines.push(line);if (lines.length === 2) {const [x, y] = lines[0].split(" ").map(Number); // 采样员人数 x,志愿者人数 yconst arrX = lines[1].split(" ").map(Number); // 每个采样员的正常效率console.log(getResult(arrX, x, y)); // 调用算法并输出结果lines.length = 0; // 清空输入缓存}
});/*** 计算最高效率* @param {number[]} arr 每个采样员的正常效率* @param {number} x 采样员人数* @param {number} y 志愿者人数* @returns {number} 最高效率*/
function getResult(arr, x, y) {// 大顶堆优先队列,堆顶元素总是:新增一个志愿者后,提升效率最多的采样员const pq = new PriorityQueue((a, b) => getAdd(b) - getAdd(a));// 将所有采样员加入优先队列,初始时采样员都不搭配志愿者for (let base of arr) {pq.offer(new Sample(base));}// 只要还有志愿者,就将其分配给采样员while (y > 0) {// 如果堆顶采样员已有四个志愿者,说明再增加志愿者也不会带来效率提升if (pq.size == 0 || pq.peek().volunteer == 4) break;// 取出堆顶采样员const s = pq.poll();// 为其新增一个志愿者,并提升相应效率s.total += getAdd(s);s.volunteer += 1;// 重新压入队列pq.offer(s);y--;}// 计算所有采样员的总效率let ans = 0;while (pq.size > 0) ans += pq.poll().total;return ans;
}/*** 采样员类*/
class Sample {constructor(base) {this.volunteer = 0; // 该采样员搭配的志愿者人数this.base = base; // 该采样员的基准效率this.total = base * 0.8; // 该采样员的搭配志愿者后的总效率,初始时采样员没有搭配志愿者,则效率只有 base * 0.8}
}/*** 计算采样员新增一个志愿者能提升的效率* @param {Sample} s 采样员对象* @returns {number} 新增效率*/
function getAdd(s) {// 如果当前采样员没有志愿者,则新增一名志愿者可以提升 base * 20% 的效率if (s.volunteer == 0) return s.base * 0.2;// 如果当前采样员搭配的志愿者数量小于等于 3 个,则新增一个志愿者可以提升 base * 10% 的效率else if (s.volunteer <= 3) return s.base * 0.1;// 如果当前采样员已有 4 个志愿者,则再新增一个志愿者不能提升效率else return 0;
}/*** 基于堆实现优先队列*/
class PriorityQueue {constructor(cpr) {this.queue = [];this.size = 0;this.cpr = cpr;}// 交换两个元素swap(i, j) {let tmp = this.queue[i];this.queue[i] = this.queue[j];this.queue[j] = tmp;}// 上浮操作swim() {let ch = this.queue.length - 1;while (ch !== 0) {let fa = Math.floor((ch - 1) / 2);const ch_node = this.queue[ch];const fa_node = this.queue[fa];if (this.cpr(ch_node, fa_node) < 0) {this.swap(ch, fa);ch = fa;} else {break;}}}// 下沉操作sink() {let fa = 0;while (true) {let ch_left = 2 * fa + 1;let ch_right = 2 * fa + 2;let ch_max;let ch_max_node;const fa_node = this.queue[fa];const ch_left_node = this.queue[ch_left];const ch_right_node = this.queue[ch_right];if (ch_left_node && ch_right_node) {if (this.cpr(ch_left_node, ch_right_node) <= 0) {ch_max = ch_left;ch_max_node = ch_left_node;} else {ch_max = ch_right;ch_max_node = ch_right_node;}} else if (ch_left_node && !ch_right_node) {ch_max = ch_left;ch_max_node = ch_left_node;} else if (!ch_left_node && ch_right_node) {ch_max = ch_right;ch_max_node = ch_right_node;} else {break;}if (this.cpr(ch_max_node, fa_node) < 0) {this.swap(ch_max, fa);fa = ch_max;} else {break;}}}// 向优先队列中加入元素offer(ele) {this.queue.push(ele);this.size++;this.swim();}// 取出最高优先级元素poll() {this.swap(0, this.queue.length - 1);this.size--;const ans = this.queue.pop();this.sink();return ans;}// 只使用最高优先级元素,不取出peek() {return this.queue[0];}
}
Java 代码
代码实现
import java.util.PriorityQueue;
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int x = sc.nextInt(); // 采样员人数int y = sc.nextInt(); // 志愿者人数Integer[] arrX = new Integer[x];for (int i = 0; i < x; i++) {arrX[i] = sc.nextInt(); // 每个采样员的正常效率}System.out.println(getResult(arrX, x, y)); // 调用算法并输出结果}/*** 计算最高效率* @param arr 每个采样员的正常效率* @param x 采样员人数* @param y 志愿者人数* @return 最高效率*/public static int getResult(Integer[] arr, int x, int y) {// 大顶堆优先队列,堆顶元素总是:新增一个志愿者后,提升效率最多的采样员PriorityQueue<Sampler> pq = new PriorityQueue<>((a, b) -> (int) (getAdd(b) - getAdd(a)));// 将所有采样员加入优先队列,初始时采样员都不搭配志愿者for (int base : arr) {pq.offer(new Sampler(0, base));}// 只要还有志愿者,就将其分配给采样员while (y > 0) {// 如果堆顶采样员已有四个志愿者,说明再增加志愿者也不会带来效率提升if (pq.isEmpty() || pq.peek().volunteer == 4) break;// 取出堆顶采样员Sampler s = pq.poll();// 为其新增一个志愿者,并提升相应效率s.total += getAdd(s);s.volunteer += 1;// 重新压入队列pq.offer(s);y--;}// 计算所有采样员的总效率double ans = 0;while (!pq.isEmpty()) ans += pq.poll().total;return (int) ans;}/*** 计算采样员新增一个志愿者能提升的效率* @param s 采样员对象* @return 新增效率*/public static double getAdd(Sampler s) {// 如果当前采样员没有志愿者,则新增一名志愿者可以提升 base * 20% 的效率if (s.volunteer == 0) return s.base * 0.2;// 如果当前采样员搭配的志愿者数量小于等于 3 个,则新增一个志愿者可以提升 base * 10% 的效率else if (s.volunteer <= 3) return s.base * 0.1;// 如果当前采样员已有 4 个志愿者,则再新增一个志愿者不能提升效率else return 0;}
}/*** 采样员类*/
class Sampler {int volunteer = 0; // 该采样员搭配的志愿者人数double base = 0; // 该采样员的基准效率double total = 0; // 该采样员的搭配志愿者后的总效率public Sampler(int volunteer, double base) {this.volunteer = volunteer;this.base = base;this.total = base * 0.8; // 初始时采样员没有搭配志愿者,则效率只有 base * 0.8}
}
Python 代码
代码实现
import queue# 输入获取
x, y = map(int, input().split()) # 采样员人数 x,志愿者人数 y
arr = list(map(int, input().split())) # 每个采样员的正常效率def getAdd(s):"""计算采样员新增一个志愿者能提升的效率:param s: 采样员对象:return: 新增效率"""if s.volunteer == 0: # 如果当前采样员没有志愿者,则新增一名志愿者可以提升 base * 20% 的效率return s.base * 0.2elif s.volunteer <= 3: # 如果当前采样员搭配的志愿者数量小于等于 3 个,则新增一个志愿者可以提升 base * 10% 的效率return s.base * 0.1else: # 如果当前采样员已有 4 个志愿者,则再新增一个志愿者不能提升效率return 0class Sampler:def __init__(self, volunteer, base):"""采样员类:param volunteer: 该采样员搭配的志愿者人数:param base: 该采样员的基准效率"""self.volunteer = volunteerself.base = baseself.total = base * 0.8 # 初始时采样员没有搭配志愿者,则效率只有 base * 0.8def __lt__(self, other):# 基于大顶堆排序,优先级为:增加一名志愿者能提升的效率return getAdd(self) > getAdd(other)def getResult(arr, x, y):"""计算最高效率:param arr: 每个采样员的正常效率:param x: 采样员人数:param y: 志愿者人数:return: 最高效率"""# 优先队列pq = queue.PriorityQueue()# 将所有采样员加入优先队列,初始时采样员都不搭配志愿者for base in arr:pq.put(Sampler(0, base))# 只要还有志愿者,就将其分配给采样员while y > 0:# 如果堆顶采样员已有四个志愿者,说明再增加志愿者也不会带来效率提升if pq.qsize() == 0 or pq.queue[0].volunteer == 4:break# 取出堆顶采样员s = pq.get()# 为其新增一个志愿者,并提升相应效率s.total += getAdd(s)s.volunteer += 1# 重新压入队列pq.put(s)y -= 1# 计算所有采样员的总效率ans = 0while pq.qsize() > 0:ans += pq.get().totalreturn int(ans)# 算法调用
print(getResult(arr, x, y))
总结
- 核心逻辑:
- 使用优先队列(大顶堆)动态分配志愿者。
- 每次将志愿者分配给能提升效率最多的采样员。
- 每个采样员最多分配 4 个志愿者,超过后无法再提升效率。
- 时间复杂度:主要取决于优先队列的操作,为
O(n log n)
。 - 空间复杂度:
O(n)
,用于存储采样员对象。
如果有其他问题,欢迎随时提问!
相关文章:
![](https://i-blog.csdnimg.cn/direct/918242775f684d628b7dcf2ee74eb48c.png)
【2024年华为OD机试】 (A卷,100分)- 总最快检测效率(Java JS PythonC/C++)
一、问题描述 题目描述 在系统、网络均正常的情况下组织核酸采样员和志愿者对人群进行核酸检测筛查。 每名采样员的效率不同,采样效率为 N 人/小时。由于外界变化,采样员的效率会以 M 人/小时为粒度发生变化,M 为采样效率浮动粒度…...
![](https://i-blog.csdnimg.cn/img_convert/cb87cb903084e6afa21045019b9f4ea2.jpeg#pic_center)
【大数据】Apache Superset:可视化开源架构
Apache Superset是什么 Apache Superset 是一个开源的现代化数据可视化和数据探索平台,主要用于帮助用户以交互式的方式分析和展示数据。有不少丰富的可视化组件,可以将数据从多种数据源(如 SQL 数据库、数据仓库、NoSQL 数据库等࿰…...
![](https://i-blog.csdnimg.cn/img_convert/960a1dc695ed722c5f5046d4468bec21.png)
LabVIEW调用不定长数组 DLL数组
在使用 LabVIEW 调用 DLL 库函数时,如果函数中的结构体包含不定长数组,直接通过 调用库函数节点(Call Library Function Node) 调用通常会遇到问题。这是因为 LabVIEW 需要与 DLL 中的数据结构完全匹配,而包含不定长数…...
![](https://i-blog.csdnimg.cn/direct/80ad96b79f0047218703e5e96c74c9cc.png)
MySQL 17 章——触发器
在实际开发中,我们经常会遇到这样的情况:有2个或者多个相关联的表,比如商品信息表和库存信息表,分别存放在两个不同的数据表中,我们在添加一条新商品记录的时候,为了保证数据的完整性,必须同时在…...
![](https://www.ngui.cc/images/no-images.jpg)
面向对象分析与设计Python版 面向对象设计方法
文章目录 前言一、职责驱动设计二、职责驱动设计-案例 前言 面向对象设计目标:在面向对象分析建立的领域模型的基础上,定义对象操作(职责)。为对象分配职责的方法有: 职责驱动设计遵循GRASP设计原则(Gene…...
![](https://www.ngui.cc/images/no-images.jpg)
GB/T 19582.1-2008主要内容
标准背景与概述 GB/T 19582.1-2008是由中国国家标准化管理委员会发布的国家标准,旨在指导和规范基于Modbus协议的工业自动化网络的设计和实施。该标准由全国工业过程测量控制和自动化标准化技术委员会(TC124)归口,并由中国机械工…...
![](https://www.ngui.cc/images/no-images.jpg)
[石榴翻译] 维吾尔语音识别 + TTS语音合成
API网址 丝路AI平台 获取 Access token 接口地址:https://open.xjguoyu.cn/api/auth/oauth/token,请求方式:GET,POST Access token是调用服务API的凭证,调用服务API之前需要获取 token。每次成功获取 token 以后只有…...
![](https://i-blog.csdnimg.cn/direct/234d728e205643969658bb5d5b5b4551.png)
算法题(32):三数之和
审题: 需要我们找到满足以下三个条件的所有三元组,并存在二维数组中返回 1.三个元素相加为0 2.三个元素的下标不可相同 3.三元组的元素不可相同 思路: 混乱的数据不利于进行操作,所以我们先进行排序 我们可以采取枚举的方法进行解…...
![](https://i-blog.csdnimg.cn/direct/b5e3a5f943ab47fdb551354f99936307.png)
webpack03
什么是source-map 将代码编译压缩之后,,可以通过source-map映射会原来的代码,,,在调试的时候可以准确找到原代码报错位置,,,进行修改 source-map有很多值: eval &#…...
![](https://i-blog.csdnimg.cn/direct/db09678f0b6b4ed9ae1d51f76f8f623b.png#pic_center)
组会 | SNN 的 BPTT(backpropagation through time)
目录 1 神经学基础知识1.1 神经元1.2 神经元之间的连接1.3 膜电位1.4 去极化与超极化 2 SNN2.1 LIF 模型2.2 BPTT 中存在的问题2.3 梯度爆炸或消失问题 前言: 本博仅为组会总结,如有谬误,请不吝指正!虽然标题为 BPTT&am…...
![](https://i-blog.csdnimg.cn/direct/c7eff380e00b43698f7fcf14103fdea5.png)
CDA数据分析师一级经典错题知识点总结(3)
1、SEMMA 的基本思想是从样本数据开始,通过统计分析与可视化技术,发现并转换最有价值的预测变量,根据变量进行构建模型,并检验模型的可用性和准确性。【强调探索性】 2、CRISP-DM模型Cross Industry Standard Process of Data Mi…...
![](https://i-blog.csdnimg.cn/direct/d854276dc44a4301b1b2ffd5bb6b7a35.jpeg)
django基于Python的电影推荐系统
Django 基于 Python 的电影推荐系统 一、系统概述 Django 基于 Python 的电影推荐系统是一款利用 Django 框架开发的智能化应用程序,旨在为电影爱好者提供个性化的电影推荐服务。该系统通过收集和分析用户的观影历史、评分数据、电影的属性信息(如类型…...
![](https://i-blog.csdnimg.cn/direct/30ccc1173dcd41cf86cf9180dfab8003.png)
JVM与Java体系结构
一、前言: Java语言和JVM简介: Java是目前最为广泛的软件开发平台之一。 JVM:跨语言的平台 随着Java7的正式发布,Java虚拟机的设计者们通过JSR-292规范基本实现在Java虚拟机平台上运行非Java语言编写的程序。 Java虚拟机根本不关心运行在其内部的程序到底是使用何…...
![](https://i-blog.csdnimg.cn/direct/b7e0fa98cd28498e9abaaa3f33d37631.png)
网络授时笔记
SNTP的全称是Simple Network Time Protocol,意思是简单网络时间协议,用来从网络中获取当前的时间,也可以称为网络授时。项目中会使用LwIP SNTP模块从服务器(pool.ntp.org)获取时间 我们使用sntp例程,sntp例程路径为D:\Espressif\…...
![](https://i-blog.csdnimg.cn/direct/f48f7400028a4fd9bc9be2a924fafde5.png)
【CSS】HTML页面定位CSS - position 属性 relative 、absolute、fixed 、sticky
目录 relative 相对定位 absolute 绝对定位 fixed 固定定位 sticky 粘性定位 position:relative 、absolute、fixed 、sticky (四选一) top:距离上面的像素 bottom:距离底部的像素 left:距离左边的像素…...
![](https://i-blog.csdnimg.cn/direct/75acd756b2904f008f71280163c56f55.png)
spark汇总
目录 描述运行模式1. Windows模式代码示例 2. Local模式3. Standalone模式 RDD描述特性RDD创建代码示例(并行化创建)代码示例(读取外部数据)代码示例(读取目录下的所有文件) 算子DAGSparkSQLSparkStreaming…...
![](https://i-blog.csdnimg.cn/direct/c3b136c8cc67455eb1ec02b4d8fb2b0e.png)
【Rust自学】11.5. 在测试中使用Result<T, E>
喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 11.5.1. 测试函数返回值为Result枚举 到目前为止,测试运行失败的原因都是因为触发了panic,但可以导致测试失败的…...
![](https://i-blog.csdnimg.cn/direct/bc82f574e9dc466ab0b3aec192f14829.png)
Sping Boot教程之五十四:Spring Boot Kafka 生产者示例
Spring Boot Kafka 生产者示例 Spring Boot 是 Java 编程语言中最流行和使用最多的框架之一。它是一个基于微服务的框架,使用 Spring Boot 制作生产就绪的应用程序只需很少的时间。Spring Boot 可以轻松创建独立的、生产级的基于 Spring 的应用程序,您可…...
![](https://i-blog.csdnimg.cn/direct/c87b0c0f60b049f09a0ebd5918f0cd2f.webp)
设计模式-结构型-组合模式
1. 什么是组合模式? 组合模式(Composite Pattern) 是一种结构型设计模式,它允许将对象组合成树形结构来表示“部分-整体”的层次结构。组合模式使得客户端对单个对象和组合对象的使用具有一致性。换句话说,组合模式允…...
![](https://i-blog.csdnimg.cn/direct/ca29c9bb8047414fb7180f070aefd9ce.png)
基于Java的推箱子游戏设计与实现
基于Java的推箱子游戏设计与实现 摘 要 社会在进步,人们生活质量也在日益提高。高强度的压力也接踵而来。社会中急需出现新的有效方式来缓解人们的压力。此次设计符合了社会需求,Java推箱子游戏可以让人们在闲暇之余,体验游戏的乐趣。具有…...
![](https://www.ngui.cc/images/no-images.jpg)
Spark vs Flink分布式数据处理框架的全面对比与应用场景解析
1. 引言 1.1 什么是分布式数据处理框架 随着数据量的快速增长,传统的单机处理方式已经无法满足现代数据处理需求。分布式数据处理框架应运而生,它通过将数据分片分布到多台服务器上并行处理,提高了任务的处理速度和效率。 分布式数据处理框…...
![](https://www.ngui.cc/images/no-images.jpg)
python_excel列表单元格字符合并、填充、复制操作
读取指定sheet页,根据规则合并指定列,填充特定字符,删除多余的列,每行复制四次,最后写入新的文件中。 import pandas as pd""" 读取指定sheet页,根据规则合并指定列,填充特定字…...
![](https://i-blog.csdnimg.cn/direct/1ad7d212b9764ee08608d4cf2336fd6e.png)
nums[:]数组切片
问题:给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 使用代码如下没有办法通过测试示例,必须将最后一行代码改成 nums[:]nums[-k:]nums[:-k]切片形式: 原因:列表的切片操作 …...
![](https://www.ngui.cc/images/no-images.jpg)
【Arthas 】Can not find Arthas under local: /root/.arthas/lib 解决办法
报错 [INFO] JAVA_HOME: /opt/java/openjdk [INFO] arthas-boot version: 4.0.4 [INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER. [1]: 12 org.springframework.boot.loader.JarLauncher 1 [ER…...
![](https://i-blog.csdnimg.cn/img_convert/72ff466fe95017d6a18f5600f8e332e1.png)
录用率23%!CCF推荐-B类,Early Access即可被SCI数据库收录,中美作者占比过半
International Journal of Human-Computer Interaction(IJHCI)创刊于1989年,由泰勒-弗朗西斯(Taylor & Francis, Inc.)出版,主要发表关于交互式计算(认知和人体工程学)、数字无障…...
![](https://i-blog.csdnimg.cn/direct/58ab61b43a4f4a33a735637ba1ff76ad.png)
IP 地址与蜜罐技术
基于IP的地址的蜜罐技术是一种主动防御策略,它能够通过在网络上布置的一些看似正常没问题的IP地址来吸引恶意者的注意,将恶意者引导到预先布置好的伪装的目标之中。 如何实现蜜罐技术 当恶意攻击者在网络中四处扫描,寻找可入侵的目标时&…...
![](https://i-blog.csdnimg.cn/direct/8506994f799d4779a114891130bce496.png)
Vue_API文档
Vue API风格 Vue 的组件可以按两种不同的风格书写:选项式 API(Vue2) 和组合式 API(Vue3) 大部分的核心概念在这两种风格之间都是通用的。熟悉了一种风格以后,你也能够很快地理解另一种风格 选项式API(Opt…...
![](https://www.ngui.cc/images/no-images.jpg)
WebSocket 设计思路
WebSocket 设计思路 1. 核心结构体 1.1 Manager (管理器) // Manager 负责管理所有WebSocket连接 type Manager struct {clients sync.Map // 存储所有客户端连接broadcast chan []byte // 广播消息通道messages chan Message // 消息处理通道config *config.WebSo…...
![](https://www.ngui.cc/images/no-images.jpg)
Jenkins持续集成与交付安装配置
Jenkins 是一款开源的持续集成(CI)和持续交付(CD)工具,它主要用于自动化软件的构建、测试和部署流程。为项目持续集成与交付功能强大的应用。下面我们来介绍下它的安装与配置。 环境准备 更新系统组件(这…...
![](https://i-blog.csdnimg.cn/direct/8eae0b8b4a25444e85ceea559a7cde0f.png)
ESP32作为Wi-Fi AP模式的测试
一、AP模式的流程 初始化阶段 (Init Phase): 1.1: Main task(主任务)初始化LwIP(轻量级TCP/IP协议栈)。 ESP_ERROR_CHECK(esp_netif_init()); 1.2: 创建和初始化Event task(事件任务)。 ESP_ERROR_CHECK…...
![](https://img-blog.csdnimg.cn/98bb3a70ea7348f2b5c5df3294066caa.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5aaW5oCq5LiN5oWM5LiN5byg,size_20,color_FFFFFF,t_70,g_se,x_16)
网站关键词掉的很快/国外域名
迭代器模式介绍 顺序访问一个集合 顺序:如数组、类数组称为顺序,而非对象,能从0,1,2…通过index访问的值 使用者无需知道集合的内部结构 示例 如果要对这三个变量进行遍历,需要写三个遍历方法 <p>…...
![](https://img-blog.csdnimg.cn/img_convert/79b84173183b236bfa5a3834041d52eb.png)
网站怎么做排名/百度推广怎么操作流程
什么是过滤器?有什么用?过滤器JavaWeb三大组件之一,它与Servlet很相似。不过滤器是用来拦截请求的,而不是处理请求的。过滤,顾名思义,就是留下我们想要的,丢掉我们不需要的。例如:某…...
![](https://img-blog.csdnimg.cn/img_convert/b40127d75693f7de24cffddba477fdf7.png)
企业网站优化找哪家/百度打广告多少钱一个月
解决方案分红两步:php(1)调用unoconv命令将 doc、ppt 转 pdfshell(2)使用 imagemagick将 pdf 转图片windows步骤dom1.安装unoconv测试sudo apt-get install unoconv安装是否成功字体unoconv --version2.安装imagemagickspasudo apt-get install imagemagick是否安装…...
![](http://upload-images.jianshu.io/upload_images/5712789-386fac78e62052fc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
响应式电影网站/宁波seo在线优化方案公司
开发工具 1.Eclipse IDE:采用Maven项目管理,模块化。 2.代码生成:通过界面方式简单配置,自动生成相应代码,目前包括三种生成方式(增删改查):单表、一对多、树结构。生成后的代码如果…...
![](https://s1.51cto.com/attachment/201010/2/2221160_1286037337bQZR.png)
网站建设流程信息/网络推广100种方法
使用..表示上一层目录,使用.表示当前目录。文件夹或文件前面有.,则表示是掩藏文件 Home,分为root的Home和一般用户的home Bin目录里存放了常用的执行档,例如date、cal等。Bin和usr/bin的内容大致相同。预设情况下Usr/local/bin是空…...
![](/images/no-images.jpg)
建设网站需要哪些手续/下载百度网盘app
/***题目:旅店信息管理系统**小组成员:闫若琳 戴雨晨 马渊沐 张子飞 李闯王浩 崔以博 孙浩浩 李春普 温健成*/#include #include #include #include #define MIN 1#define MAX 30#define LEN sizeof(struct Hotel)//用LEN代替结构体的"长度"void regeist(…...