当前位置: 首页 > 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 是用来从一个分…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...