当前位置: 首页 > news >正文

【2024年华为OD机试】(A卷,100分)- 等和子数组最小和(Java JS PythonC/C++)

在这里插入图片描述

一、问题描述

题目描述

给定一个数组nums,将元素分为若干个组,使得每组和相等,求出满足条件的所有分组中,组内元素和的最小值。

输入描述

第一行输入 m
接着输入m个数,表示此数组nums
数据范围:1<=m<=50, 1<=nums[i]<=50

输出描述

最小拆分数组和

用例

输入

7
4 3 2 3 5 2 1

输出

5

说明

可以等分的情况有:

  • 4 个子集(5),(1,4),(2,3),(2,3)
  • 2 个子集(5, 1, 4),(2,3, 2,3)

但最小的为5。

题目解析

本题算是划分为k个相等的子集的变种题,本题同样是要将数组划分为k个和相等的子集。

本题要我们求解:最小拆分数组和,其实就是求解:最小子集和,其实就是求解,最大k值。因为k值越大,则对应的子集的和越小。

这里k的求解很简单,首先,我们可以猜想下k的上限是多少?

比如数组所有元素都相等,则k === m,即每个元素都能作为一个子集,因此我们可以让k从m开始尝试,如果不行,则k–,直到k=1。

而验证nums是否可以划分为k层,其实就是判断nums是否可以划分为k个和相等的子集,这个判断逻辑可以复用划分为k个相等的子集中的逻辑。

二、JavaScript算法源码

以下是对提供的 JavaScript 代码的中文详细注释和逻辑讲解:


JavaScript 代码实现

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");// 创建 readline 接口,用于从控制台读取输入
const rl = readline.createInterface({input: process.stdin,output: process.stdout,
});// 存储输入行的数组
const lines = [];// 监听每一行输入
rl.on("line", (line) => {lines.push(line); // 将输入行存入 lines 数组// 当输入行数为 2 时,表示输入完成if (lines.length === 2) {const m = parseInt(lines[0]); // 解析第一行输入,获取 m 的值const arr = lines[1].split(" ").map(Number); // 解析第二行输入,获取数组 arr// 调用 getResult 函数计算结果并输出console.log(getResult(arr, m));// 清空 lines 数组,准备接收下一组输入lines.length = 0;}
});/*** 计算将数组划分为 m 个子集的最大子集和* @param {number[]} arr - 输入的数组* @param {number} m - 子集的数量* @returns {number} - 最大子集和*/
function getResult(arr, m) {// 对数组进行降序排序const sum = arr.sort((a, b) => b - a).reduce((p, c) => p + c);// 从 m 开始递减,尝试将数组划分为 m 个子集while (m) {// 如果可以将数组划分为 m 个子集,返回子集和if (canPartitionMSubsets([...arr], sum, m)) return sum / m;m--;}// 如果无法划分,返回数组总和return sum;
}/*** 判断是否可以将数组划分为 m 个子集,每个子集的和为 subSum* @param {number[]} arr - 输入的数组* @param {number} sum - 数组的总和* @param {number} m - 子集的数量* @returns {boolean} - 是否可以划分*/
function canPartitionMSubsets(arr, sum, m) {// 如果总和不能被 m 整除,无法划分if (sum % m !== 0) return false;// 计算每个子集的目标和const subSum = sum / m;// 如果数组中的最大值大于目标和,无法划分if (subSum < arr[0]) return false;// 如果数组中的某个元素等于目标和,直接将其作为一个子集while (arr[0] === subSum) {arr.shift(); // 移除该元素m--; // 减少子集数量}// 初始化 m 个桶,用于存储每个子集的当前和const buckets = new Array(m).fill(0);// 调用 partition 函数进行递归划分return partition(arr, 0, buckets, subSum);
}/*** 递归尝试将数组划分为 m 个子集* @param {number[]} arr - 输入的数组* @param {number} index - 当前处理的数组索引* @param {number[]} buckets - 存储每个子集当前和的数组* @param {number} subSum - 每个子集的目标和* @returns {boolean} - 是否可以划分*/
function partition(arr, index, buckets, subSum) {// 如果所有元素都已处理,返回 trueif (index === arr.length) return true;// 获取当前处理的元素const select = arr[index];// 尝试将当前元素放入每个桶中for (let i = 0; i < buckets.length; i++) {// 如果当前桶和前一个桶的和相同,跳过(避免重复计算)if (i > 0 && buckets[i] === buckets[i - 1]) continue;// 如果当前元素可以放入当前桶if (select + buckets[i] <= subSum) {buckets[i] += select; // 将当前元素放入桶中// 递归处理下一个元素if (partition(arr, index + 1, buckets, subSum)) return true;buckets[i] -= select; // 回溯:将当前元素从桶中移除}}// 如果无法放入任何桶,返回 falsereturn false;
}

代码讲解

1. 输入处理
  • 使用 readline 模块从控制台读取输入。
  • 将输入的两行数据分别解析为 m(子集数量)和 arr(数组)。
  • 当输入完成后,调用 getResult 函数计算结果并输出。
2. 主逻辑:getResult 函数
  • 对数组进行降序排序,并计算数组的总和 sum
  • m 开始递减,尝试将数组划分为 m 个子集。
  • 如果成功划分,返回子集和 sum / m;否则返回数组总和 sum
3. 判断是否可以划分:canPartitionMSubsets 函数
  • 检查总和 sum 是否能被 m 整除,如果不能,直接返回 false
  • 计算每个子集的目标和 subSum
  • 如果数组中的最大值大于 subSum,无法划分,返回 false
  • 如果数组中的某个元素等于 subSum,直接将其作为一个子集,并减少子集数量 m
  • 初始化 m 个桶,调用 partition 函数进行递归划分。
4. 递归划分:partition 函数
  • 如果所有元素都已处理,返回 true
  • 尝试将当前元素放入每个桶中:
    • 如果当前桶和前一个桶的和相同,跳过(避免重复计算)。
    • 如果当前元素可以放入当前桶,递归处理下一个元素。
    • 如果无法放入任何桶,返回 false

示例解析

输入
3
4 3 2 3 5 2 1
运行结果
5
  • 解析:
    • 数组 [4, 3, 2, 3, 5, 2, 1] 的总和为 20
    • 尝试划分为 3 个子集,目标和为 20 / 3 ≈ 6.67,无法整除。
    • 尝试划分为 2 个子集,目标和为 10,可以划分为 [5, 4, 1][3, 3, 2, 2]
    • 返回最大子集和 5

总结

  • 该代码通过递归和回溯的方式,尝试将数组划分为 m 个子集。
  • 使用降序排序和剪枝优化,提高了算法效率。
  • 代码逻辑清晰,适用于解决类似划分问题的场景。

如果有其他问题,欢迎随时提问!

三、Java算法源码

以下是对提供的 Java 代码的中文详细注释和逻辑讲解,同时修复了越界异常问题:


Java 代码实现

import java.util.LinkedList;
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);// 读取子集数量 mint m = sc.nextInt();// 创建链表存储数组元素LinkedList<Integer> link = new LinkedList<>();for (int i = 0; i < m; i++) {link.add(sc.nextInt()); // 读取数组元素并添加到链表中}// 调用 getResult 函数计算结果并输出System.out.println(getResult(link, m));}/*** 计算将数组划分为 m 个子集的最大子集和* @param link - 输入的链表* @param m - 子集的数量* @return - 最大子集和*/public static int getResult(LinkedList<Integer> link, int m) {// 对链表进行降序排序link.sort((a, b) -> b - a);// 计算链表元素的总和int sum = 0;for (Integer ele : link) {sum += ele;}// 从 m 开始递减,尝试将数组划分为 m 个子集while (m > 0) {// 创建链表的副本,避免修改原链表LinkedList<Integer> link_cp = new LinkedList<>(link);// 如果可以将数组划分为 m 个子集,返回子集和if (canPartitionMSubsets(link_cp, sum, m)) return sum / m;m--;}// 如果无法划分,返回数组总和return sum;}/*** 判断是否可以将数组划分为 m 个子集,每个子集的和为 subSum* @param link - 输入的链表* @param sum - 数组的总和* @param m - 子集的数量* @return - 是否可以划分*/public static boolean canPartitionMSubsets(LinkedList<Integer> link, int sum, int m) {// 如果总和不能被 m 整除,无法划分if (sum % m != 0) return false;// 计算每个子集的目标和int subSum = sum / m;// 如果数组中的最大值大于目标和,无法划分if (subSum < link.get(0)) return false;// 如果数组中的某个元素等于目标和,直接将其作为一个子集// 修复越界异常:增加链表非空检查while (link.size() > 0 && link.get(0) == subSum) {link.removeFirst(); // 移除该元素m--; // 减少子集数量}// 初始化 m 个桶,用于存储每个子集的当前和int[] buckets = new int[m];// 调用 partition 函数进行递归划分return partition(link, 0, buckets, subSum);}/*** 递归尝试将数组划分为 m 个子集* @param link - 输入的链表* @param index - 当前处理的链表索引* @param buckets - 存储每个子集当前和的数组* @param subSum - 每个子集的目标和* @return - 是否可以划分*/public static boolean partition(LinkedList<Integer> link, int index, int[] buckets, int subSum) {// 如果所有元素都已处理,返回 trueif (index == link.size()) return true;// 获取当前处理的元素int select = link.get(index);// 尝试将当前元素放入每个桶中for (int i = 0; i < buckets.length; i++) {// 如果当前桶和前一个桶的和相同,跳过(避免重复计算)if (i > 0 && buckets[i] == buckets[i - 1]) continue;// 如果当前元素可以放入当前桶if (select + buckets[i] <= subSum) {buckets[i] += select; // 将当前元素放入桶中// 递归处理下一个元素if (partition(link, index + 1, buckets, subSum)) return true;buckets[i] -= select; // 回溯:将当前元素从桶中移除}}// 如果无法放入任何桶,返回 falsereturn false;}
}

代码讲解

1. 输入处理
  • 使用 Scanner 从控制台读取输入。
  • 读取子集数量 m 和数组元素,并存储在 LinkedList 中。
2. 主逻辑:getResult 函数
  • 对链表进行降序排序,并计算链表元素的总和 sum
  • m 开始递减,尝试将数组划分为 m 个子集。
  • 如果成功划分,返回子集和 sum / m;否则返回数组总和 sum
3. 判断是否可以划分:canPartitionMSubsets 函数
  • 检查总和 sum 是否能被 m 整除,如果不能,直接返回 false
  • 计算每个子集的目标和 subSum
  • 如果数组中的最大值大于 subSum,无法划分,返回 false
  • 如果数组中的某个元素等于 subSum,直接将其作为一个子集,并减少子集数量 m
  • 初始化 m 个桶,调用 partition 函数进行递归划分。
4. 递归划分:partition 函数
  • 如果所有元素都已处理,返回 true
  • 尝试将当前元素放入每个桶中:
    • 如果当前桶和前一个桶的和相同,跳过(避免重复计算)。
    • 如果当前元素可以放入当前桶,递归处理下一个元素。
    • 如果无法放入任何桶,返回 false

修复越界异常

canPartitionMSubsets 函数中,修复了以下代码的越界异常:

while (link.get(0) == subSum) { // 原代码可能越界

修改为:

while (link.size() > 0 && link.get(0) == subSum) { // 增加链表非空检查

示例解析

输入
5
5 5 5 5 5
运行结果
5
  • 解析:
    • 数组 [5, 5, 5, 5, 5] 的总和为 25
    • 尝试划分为 5 个子集,目标和为 5,可以划分为 [5], [5], [5], [5], [5]
    • 返回最大子集和 5

总结

  • 该代码通过递归和回溯的方式,尝试将数组划分为 m 个子集。
  • 修复了越界异常问题,确保代码的健壮性。
  • 代码逻辑清晰,适用于解决类似划分问题的场景。

如果有其他问题,欢迎随时提问!

四、Python算法源码

以下是对提供的 Python 代码的中文详细注释和逻辑讲解:


Python 代码实现

# 输入获取
m = int(input())  # 读取子集数量 m
link = list(map(int, input().split()))  # 读取数组元素并存储在列表中# 算法入口
def getResult(link, m):# 对数组进行降序排序link.sort(reverse=True)# 计算数组元素的总和sumV = 0for ele in link:sumV += ele# 从 m 开始递减,尝试将数组划分为 m 个子集while m > 0:# 创建数组的副本,避免修改原数组if canPartitionMSubsets(link[:], sumV, m):return int(sumV / m)  # 如果成功划分,返回子集和m -= 1# 如果无法划分,返回数组总和return sumVdef canPartitionMSubsets(link, sumV, m):# 如果总和不能被 m 整除,无法划分if sumV % m != 0:return False# 计算每个子集的目标和subSum = sumV / m# 如果数组中的最大值大于目标和,无法划分if subSum < link[0]:return False# 如果数组中的某个元素等于目标和,直接将其作为一个子集while len(link) > 0 and link[0] == subSum:link.pop(0)  # 移除该元素m -= 1  # 减少子集数量# 初始化 m 个桶,用于存储每个子集的当前和buckets = [0] * m# 调用 partition 函数进行递归划分return partition(link, 0, buckets, subSum)def partition(link, index, buckets, subSum):# 如果所有元素都已处理,返回 Trueif index == len(link):return True# 获取当前处理的元素select = link[index]# 尝试将当前元素放入每个桶中for i in range(len(buckets)):# 如果当前桶和前一个桶的和相同,跳过(避免重复计算)if i > 0 and buckets[i] == buckets[i - 1]:continue# 如果当前元素可以放入当前桶if select + buckets[i] <= subSum:buckets[i] += select  # 将当前元素放入桶中# 递归处理下一个元素if partition(link, index + 1, buckets, subSum):return Truebuckets[i] -= select  # 回溯:将当前元素从桶中移除# 如果无法放入任何桶,返回 Falsereturn False# 算法调用
print(getResult(link, m))

代码讲解

1. 输入处理
  • 使用 input() 函数从控制台读取输入。
  • 读取子集数量 m 和数组元素,并存储在列表 link 中。
2. 主逻辑:getResult 函数
  • 对数组进行降序排序,并计算数组元素的总和 sumV
  • m 开始递减,尝试将数组划分为 m 个子集。
  • 如果成功划分,返回子集和 sumV / m;否则返回数组总和 sumV
3. 判断是否可以划分:canPartitionMSubsets 函数
  • 检查总和 sumV 是否能被 m 整除,如果不能,直接返回 False
  • 计算每个子集的目标和 subSum
  • 如果数组中的最大值大于 subSum,无法划分,返回 False
  • 如果数组中的某个元素等于 subSum,直接将其作为一个子集,并减少子集数量 m
  • 初始化 m 个桶,调用 partition 函数进行递归划分。
4. 递归划分:partition 函数
  • 如果所有元素都已处理,返回 True
  • 尝试将当前元素放入每个桶中:
    • 如果当前桶和前一个桶的和相同,跳过(避免重复计算)。
    • 如果当前元素可以放入当前桶,递归处理下一个元素。
    • 如果无法放入任何桶,返回 False

示例解析

输入
5
5 5 5 5 5
运行结果
5
  • 解析:
    • 数组 [5, 5, 5, 5, 5] 的总和为 25
    • 尝试划分为 5 个子集,目标和为 5,可以划分为 [5], [5], [5], [5], [5]
    • 返回最大子集和 5

总结

  • 该代码通过递归和回溯的方式,尝试将数组划分为 m 个子集。
  • 使用降序排序和剪枝优化,提高了算法效率。
  • 代码逻辑清晰,适用于解决类似划分问题的场景。

如果有其他问题,欢迎随时提问!

五、C/C++算法源码:

以下是为 C++ 代码的实现,并附上详细的中文注释和逻辑讲解:


C++ 代码实现

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;// 判断是否可以将数组划分为 m 个子集
bool partition(vector<int>& link, int index, vector<int>& buckets, int subSum);// 判断是否可以将数组划分为 m 个子集,每个子集的和为 subSum
bool canPartitionMSubsets(vector<int> link, int sumV, int m) {// 如果总和不能被 m 整除,无法划分if (sumV % m != 0) return false;// 计算每个子集的目标和int subSum = sumV / m;// 如果数组中的最大值大于目标和,无法划分if (subSum < link[0]) return false;// 如果数组中的某个元素等于目标和,直接将其作为一个子集while (!link.empty() && link[0] == subSum) {link.erase(link.begin()); // 移除该元素m--; // 减少子集数量}// 初始化 m 个桶,用于存储每个子集的当前和vector<int> buckets(m, 0);// 调用 partition 函数进行递归划分return partition(link, 0, buckets, subSum);
}// 递归尝试将数组划分为 m 个子集
bool partition(vector<int>& link, int index, vector<int>& buckets, int subSum) {// 如果所有元素都已处理,返回 trueif (index == link.size()) return true;// 获取当前处理的元素int select = link[index];// 尝试将当前元素放入每个桶中for (int i = 0; i < buckets.size(); i++) {// 如果当前桶和前一个桶的和相同,跳过(避免重复计算)if (i > 0 && buckets[i] == buckets[i - 1]) continue;// 如果当前元素可以放入当前桶if (select + buckets[i] <= subSum) {buckets[i] += select; // 将当前元素放入桶中// 递归处理下一个元素if (partition(link, index + 1, buckets, subSum)) return true;buckets[i] -= select; // 回溯:将当前元素从桶中移除}}// 如果无法放入任何桶,返回 falsereturn false;
}// 算法入口
int getResult(vector<int>& link, int m) {// 对数组进行降序排序sort(link.begin(), link.end(), greater<int>());// 计算数组元素的总和int sumV = 0;for (int ele : link) {sumV += ele;}// 从 m 开始递减,尝试将数组划分为 m 个子集while (m > 0) {// 创建数组的副本,避免修改原数组if (canPartitionMSubsets(link, sumV, m)) {return sumV / m; // 如果成功划分,返回子集和}m--;}// 如果无法划分,返回数组总和return sumV;
}int main() {// 输入获取int m;cin >> m; // 读取子集数量 mvector<int> link;int num;while (cin >> num) {link.push_back(num); // 读取数组元素并存储在 vector 中if (cin.get() == '\n') break; // 如果遇到换行符,结束输入}// 算法调用cout << getResult(link, m) << endl;return 0;
}

代码讲解

1. 输入处理
  • 使用 cin 从控制台读取输入。
  • 读取子集数量 m 和数组元素,并存储在 vector<int> link 中。
2. 主逻辑:getResult 函数
  • 对数组进行降序排序,并计算数组元素的总和 sumV
  • m 开始递减,尝试将数组划分为 m 个子集。
  • 如果成功划分,返回子集和 sumV / m;否则返回数组总和 sumV
3. 判断是否可以划分:canPartitionMSubsets 函数
  • 检查总和 sumV 是否能被 m 整除,如果不能,直接返回 false
  • 计算每个子集的目标和 subSum
  • 如果数组中的最大值大于 subSum,无法划分,返回 false
  • 如果数组中的某个元素等于 subSum,直接将其作为一个子集,并减少子集数量 m
  • 初始化 m 个桶,调用 partition 函数进行递归划分。
4. 递归划分:partition 函数
  • 如果所有元素都已处理,返回 true
  • 尝试将当前元素放入每个桶中:
    • 如果当前桶和前一个桶的和相同,跳过(避免重复计算)。
    • 如果当前元素可以放入当前桶,递归处理下一个元素。
    • 如果无法放入任何桶,返回 false

示例解析

输入
5
5 5 5 5 5
运行结果
5
  • 解析:
    • 数组 [5, 5, 5, 5, 5] 的总和为 25
    • 尝试划分为 5 个子集,目标和为 5,可以划分为 [5], [5], [5], [5], [5]
    • 返回最大子集和 5

总结

  • 该代码通过递归和回溯的方式,尝试将数组划分为 m 个子集。
  • 使用降序排序和剪枝优化,提高了算法效率。
  • 代码逻辑清晰,适用于解决类似划分问题的场景。

如果有其他问题,欢迎随时提问!

相关文章:

【2024年华为OD机试】(A卷,100分)- 等和子数组最小和(Java JS PythonC/C++)

一、问题描述 题目描述 给定一个数组nums&#xff0c;将元素分为若干个组&#xff0c;使得每组和相等&#xff0c;求出满足条件的所有分组中&#xff0c;组内元素和的最小值。 输入描述 第一行输入 m 接着输入m个数&#xff0c;表示此数组nums 数据范围&#xff1a;1<m&…...

NFS服务

nfs文件系统 NFS:NetworkFileSystem网络文件系统&#xff0c;基于内核的文件系统。 服务安装 不固定端口启动&#xff0c;会注册到rpcbind&#xff08;固定端口&#xff09;服务上&#xff0c; 局域网适用[rootvm ~]# yum -y install nfs-utils # 依赖安装rpcbind [ro…...

RabbitMQ 交换机、队列和路由键的命名规范

在 RabbitMQ 中&#xff0c;使用 Topic Exchange 模式时&#xff0c;交换机、队列和路由键的命名规范是非常重要的&#xff0c;尤其是在多环境和多微服务的场景中。合理的命名规范可以提高消息系统的可维护性、可扩展性以及可读性。以下是一些关于 Topic Exchange 模式中交换机…...

腾讯云AI代码助手编程挑战赛-刑说

作品简介 鉴于当代普法力度不够大&#xff0c;这个刑说可以帮助大家更好的普及法律知识 技术架构 采用了全后端分离的架构&#xff0c;前端使用Vue.js&#xff0c;腾讯云的AI服务处理自然语言理解与生成。 实现过程 开发环境、开发流程 系统&#xff1a;win11 开发工具&…...

【测试】持续集成CI/CD

近期更新完毕&#xff0c;建议关注收藏点赞&#xff5e; 目录 概括gitJenkinspostman集成jenkins代码集成jenkins 概括 CI/CD stands for Continuous Integration and Continuous Deployment 定义 团队成果持续集成到公共平台。一天可以集成1次or多次 本地代码管理 git 远程代…...

阿里云直播Web

官方文档&#xff1a;Web播放器SDK常见问题_视频点播(VOD)-阿里云帮助中心 bug&#xff1a;播流的不稳定&#xff0c;直播总会进入 onM3u8Retry 监听&#xff0c;用户端就会黑屏&#xff0c;&#xff08;但其实并没有关播&#xff0c;正常关播进入的是pause这个监听&#xff0…...

DuckDB:PRAGMA语句动态配置数据库行为

PRAGMA语句是DuckDB从SQLite中采用的SQL扩展。PRAGMA命令可能会改变数据库引擎的内部状态&#xff0c;并可能影响引擎的后续执行或行为。本文介绍PRAGMA命令及其典型应用场景。 DuckDB PRAGMA介绍 在 DuckDB 中&#xff0c;PRAGMA 是一种编译指示&#xff08;compiler directi…...

GO通过SMTP协议发送邮件

什么是SMTP协议 SMTP&#xff08;Simple Mail Transfer Protocol&#xff0c;简单邮件传输协议&#xff09;是用于发送邮件的协议。当一个邮件服务器需要发送邮件给另一个邮件服务器时&#xff0c;它会使用SMTP协议与目标服务器建立连接&#xff0c;并传输邮件内容。SMTP协议的…...

轻量自高斯注意力机制LSGAttention模型详解及代码复现

模型背景 近年来,卷积神经网络(CNN)在高光谱图像分类领域取得了显著进展。然而,CNN面临 长距离关系建模 和 计算成本 增加的挑战。为解决这些问题,研究人员提出了基于 轻量自高斯注意(Light Self-Gaussian-Attention, LSGA) 机制的视觉转换器(Vision Transformer, VIT),旨…...

解读若依框架中的`@Excel` 和 `@Excels` 注解

文章目录 一、Excels 注解详解1.1 适用场景1.2 作用与好处 二、Excel 注解详解2.1 核心属性解析2.2 高级用法2.3 综合应用案例 三、总结 解读若依框架中的 Xss 注解博客&#xff1a;解读若依框架中的 Xss 注解 接下来我们将对若依框架中的 Excel 和 Excels 注解进行更加详细的…...

云商城--基础数据处理和分布式文件存储

第2章 基础数据处理和分布式文件存储 1.分布式文件存储系统Ceph学习 ​ 1).掌握Ceph架构 ​ 2).掌握Ceph组件 ​ 3).搭建Ceph集群(了解) 2.Ceph使用 ​ 1).基于Ceph实现文件上传 ​ 2).基于Ceph实现文件下载 3.SKU、SPU管理 ​ 1).掌握SKU和SPU关系 ​ 2).理解商品发…...

六十九:基于openssl实战验证RSA

RSA&#xff08;Rivest-Shamir-Adleman&#xff09;是一种非对称加密算法&#xff0c;广泛应用于数据加密和数字签名领域。在实际开发和学习过程中&#xff0c;理解 RSA 的工作原理和使用场景非常重要。本文将以 OpenSSL 工具为基础&#xff0c;通过实例操作来验证和理解 RSA 的…...

Three.js 用户交互:构建沉浸式3D体验的关键

文章目录 前言一、基本交互&#xff1a;鼠标与触摸事件二、高级交互&#xff1a;键盘控制与游戏手柄支持三、物理模拟与碰撞检测四、手势识别与多点触控五、增强现实&#xff08;AR&#xff09;与虚拟现实&#xff08;VR&#xff09;六、触觉反馈与震动效果七、语音控制八、眼球…...

Android车机DIY开发之学习篇(五)默认应用修改

Android车机DIY开发之学习篇(五)默认应用修改 android默认应用位置 sdk/packages/apps InitRC配置 应用安装的目录 /system/priv-app 该路径存放一些系统底层的应用&#xff0c;比如Setting&#xff0c;systemUI等。该目录中的app拥有较高的系统权限&#xff0c;而且如果要使…...

linux 设置mysql 外网访问

1、修改 MySQL 配置文件 找到并编辑配置文件&#xff1a;在Linux系统中&#xff0c;MySQL的配置文件通常是/etc/mysql/my.cnf&#xff0c;使用命令sudo vim /etc/mysql/my.cnf打开文件。 注释或修改 bindaddress&#xff1a;找到bindaddress 127.0.0.1&#xff0c;将其注释掉…...

SQL UNION 操作符

SQL UNION 操作符 SQL UNION 操作符用于合并两个或多个 SELECT 语句的结果集。它将多个结果集组合成一个单独的结果集&#xff0c;并去除重复的行。为了使用 UNION&#xff0c;每个 SELECT 语句必须具有相同的列数&#xff0c;并且对应列的数据类型必须兼容。 语法 SELECT c…...

c++ 17 constexpr

未来已来&#xff1a;从SFINAE到concepts #include <type_traits> #include <vector> #include <list> #include <iostream> // 一个通用的容器打印函数&#xff0c;支持任何带 begin()/end() 的容器 template<typename Container> …...

Java QueryWrapper groupBy自定义字段,以及List<Map>转List<Entity>

Java queryWrapper groupby自定义字段 String sql "data_id,(select value from lz_html a where a.data_id lz_html.data_id and class_nametest-item-status) status," "(select value from lz_html a where a.data_id lz_html.data_id and class_nametes…...

【Rust自学】11.7. 按测试的名称运行测试

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 11.7.1. 按名称运行测试的子集 如果想要选择运行的测试&#xff0c;就将测试的名称&#xff08;一个或多个&#xff09;作为cargo test的…...

Git:Cherry-Pick 的使用场景及使用流程

前面我们说了 Git合并、解决冲突、强行回退等解决方案 >> 点击查看 这里再说一下 Cherry-Pick功能&#xff0c;Cherry-Pick不是merge&#xff0c;只是把部分功能代码Cherry-Pick到远程的目标分支 git cherry-pick功能简介&#xff1a; git cherry-pick 是用来从一个分…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践

前言&#xff1a;本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中&#xff0c;跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南&#xff0c;你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案&#xff0c;并结合内网…...

机器学习的数学基础:线性模型

线性模型 线性模型的基本形式为&#xff1a; f ( x ) ω T x b f\left(\boldsymbol{x}\right)\boldsymbol{\omega}^\text{T}\boldsymbol{x}b f(x)ωTxb 回归问题 利用最小二乘法&#xff0c;得到 ω \boldsymbol{\omega} ω和 b b b的参数估计$ \boldsymbol{\hat{\omega}}…...