【2024年华为OD机试】 (C卷,100分)- 用连续自然数之和来表达整数(Java JS PythonC/C++)

在这里插入图片描述

一、问题描述

题目描述

一个整数可以由连续的自然数之和来表示。

给定一个整数,计算该整数有几种连续自然数之和的表达式,且打印出每种表达式。

输入描述

一个目标整数T (1 <=T<= 1000)

输出描述

该整数的所有表达式和表达式的个数。

如果有多种表达式,输出要求为:自然数个数最少的表达式优先输出,每个表达式中按自然数递增的顺序输出,具体的格式参见样例。

在每个测试数据结束时,输出一行“Result:X”,其中X是最终的表达式个数。

用例

用例1

输入

9

输出

9=9
9=4+5
9=2+3+4
Result:3

说明
整数 9 有三种表示方法,第1个表达式只有1个自然数,最先输出,

第2个表达式有2个自然数,第2次序输出,

第3个表达式有3个自然数,最后输出。每个表达式中的自然数都是按递增次序输出的。数字与符号之间无空格。

用例2

输入

10

输出

10=10
10=1+2+3+4
Result:2

题目解析

考察点

考察滑动窗口算法和数组操作。

解析思路

  1. 生成自然数数组:首先生成一个从1到目标整数T的自然数数组arr。例如,如果目标整数是9,则生成数组[1, 2, 3, 4, 5, 6, 7, 8, 9]
  2. 初始化指针和变量:使用两个指针leftright,初始时都指向数组的起始位置(索引0)。同时,初始化一个变量sum用于存储当前窗口内元素的和,初始值为arr[0]
  3. 滑动窗口逻辑
    • 移动right指针right指针从左向右移动,每次移动后计算从leftright之间的子数组和,更新sum的值。
    • 判断sum与目标整数的关系
      • 如果sum > target,则移动left指针向右一位,并从sum中减去arr[left]的值,缩小窗口。
      • 如果sum === target,则将当前窗口内的元素作为一个表达式保存起来。然后,同时移动leftright指针,更新sum的值为sum += arr[right] - arr[left]。注意检查right指针是否越界。
      • 如果sum < target,则移动right指针向右一位,并将arr[right]的值加到sum中,扩大窗口。
  4. 结束条件:当left指针移动到数组尾部时,结束搜索。
  5. 输出结果:按照自然数个数从少到多的顺序输出所有找到的表达式,并在最后输出表达式的总数。

注意事项

  • 边界检查:在移动right指针时,要注意检查是否越界。
  • 表达式格式:输出的表达式中,数字与符号之间无空格,确保格式正确。
  • 效率考虑:滑动窗口算法的时间复杂度为O(n),适用于本题的规模。

二、JavaScript算法源码

以下是 JavaScript 代码的详细中文注释和讲解:


JavaScript 代码

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline"); // 引入 readline 模块,用于读取控制台输入// 创建 readline 接口
const rl = readline.createInterface({input: process.stdin,  // 输入流为标准输入output: process.stdout, // 输出流为标准输出
});// 监听输入事件
rl.on("line", (line) => {getResult(parseInt(line)); // 调用 getResult 方法,传入输入的整数
});// 主逻辑函数
function getResult(t) {// 创建一个数组,内容为 1 到 t 的连续整数const arr = new Array(t).fill(0).map((_, i) => i + 1);// 用于存储所有满足条件的子数组const ans = [];// 初始化双指针 l 和 r,以及当前子数组的和 sumlet l = 0; // 左指针let r = 1; // 右指针let sum = arr[l]; // 当前子数组的和// 使用滑动窗口算法遍历数组while (l < t) {if (sum > t) {// 如果当前子数组的和大于 t,移动左指针并减去对应的值sum -= arr[l++];} else if (sum == t) {// 如果当前子数组的和等于 t,将其加入结果集ans.push(arr.slice(l, r));// 移动左指针并减去对应的值sum -= arr[l++];// 如果右指针超出数组范围,退出循环if (r >= t) break;// 移动右指针并加上对应的值sum += arr[r++];} else {// 如果当前子数组的和小于 t,移动右指针并加上对应的值sum += arr[r++];}}// 对结果集中的子数组按长度排序,并输出ans.sort((a, b) => a.length - b.length) // 按子数组长度从小到大排序.forEach((sub) => {console.log(`${t}=${sub.join("+")}`); // 输出子数组});// 输出满足条件的子数组的总数console.log(`Result:${ans.length}`);
}

详细讲解


1. 输入获取
const readline = require("readline"); // 引入 readline 模块// 创建 readline 接口
const rl = readline.createInterface({input: process.stdin,  // 输入流为标准输入output: process.stdout, // 输出流为标准输出
});// 监听输入事件
rl.on("line", (line) => {getResult(parseInt(line)); // 调用 getResult 方法,传入输入的整数
});
  • 功能:
    • 使用 readline 模块从控制台读取输入。
    • 监听 line 事件,当用户输入一行内容时,调用 getResult 方法。
  • 说明:
    • parseInt(line) 将输入的字符串转换为整数。

2. 初始化数组
const arr = new Array(t).fill(0).map((_, i) => i + 1);
  • 功能:
    • 创建一个长度为 t 的数组 arr
    • 数组内容为 1t 的连续整数。
  • 说明:
    • new Array(t).fill(0) 创建一个长度为 t 的数组,并用 0 填充。
    • map((_, i) => i + 1) 将数组内容替换为 1t 的连续整数。
    • 例如,如果 t = 5,则 arr = [1, 2, 3, 4, 5]

3. 滑动窗口算法
let l = 0; // 左指针
let r = 1; // 右指针
let sum = arr[l]; // 当前子数组的和while (l < t) {if (sum > t) {sum -= arr[l++]; // 如果和大于 t,移动左指针} else if (sum == t) {ans.push(arr.slice(l, r)); // 如果和等于 t,记录子数组sum -= arr[l++]; // 移动左指针if (r >= t) break; // 如果右指针超出范围,退出循环sum += arr[r++]; // 移动右指针} else {sum += arr[r++]; // 如果和小于 t,移动右指针}
}
  • 功能:
    • 使用滑动窗口算法遍历数组,找到所有和为 t 的连续子数组。
  • 说明:
    • lr 分别表示滑动窗口的左边界和右边界。
    • sum 表示当前窗口内元素的和。
    • 如果 sum > t,移动左指针并减去对应的值。
    • 如果 sum == t,记录当前子数组,并移动左指针。
    • 如果 sum < t,移动右指针并加上对应的值。

4. 结果排序与输出
ans.sort((a, b) => a.length - b.length) // 按子数组长度从小到大排序.forEach((sub) => {console.log(`${t}=${sub.join("+")}`); // 输出子数组});console.log(`Result:${ans.length}`); // 输出满足条件的子数组的总数
  • 功能:
    • 对结果集中的子数组按长度从小到大排序。
    • 使用 join("+") 将子数组拼接成字符串并输出。
    • 输出满足条件的子数组的总数。
  • 说明:
    • sort((a, b) => a.length - b.length) 按子数组长度排序。
    • join("+") 将数组元素用 + 拼接成字符串。
    • 例如,子数组 [2, 3, 4] 会被拼接为 2+3+4

代码运行示例

示例 1:

输入:

5

输出:

5=5
5=2+3
Result:2

解释:

  • 数组 arr = [1, 2, 3, 4, 5]
  • 满足条件的子数组:
    • [5]
    • [2, 3]
  • 总数为 2

示例 2:

输入:

15

输出:

15=15
15=7+8
15=4+5+6
15=1+2+3+4+5
Result:4

解释:

  • 数组 arr = [1, 2, 3, ..., 15]
  • 满足条件的子数组:
    • [15]
    • [7, 8]
    • [4, 5, 6]
    • [1, 2, 3, 4, 5]
  • 总数为 4

总结

  1. 功能:

    • 找到所有和为 t 的连续子数组。
    • 按子数组长度从小到大输出结果。
  2. 优点:

    • 使用滑动窗口算法,时间复杂度为 O(n),效率高。
    • 代码逻辑清晰,易于理解。
  3. 适用场景:

    • 适用于需要查找连续子数组满足特定条件的场景。

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

三、Java算法源码

以下是 Java 代码的详细中文注释和讲解:


Java 代码

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import java.util.StringJoiner;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in); // 创建 Scanner 对象,用于读取输入getResult(sc.nextInt()); // 调用 getResult 方法,传入输入的整数}public static void getResult(int t) {// 创建一个数组,内容为 1 到 t 的连续整数int[] arr = new int[t];for (int i = 0; i < t; i++) {arr[i] = i + 1;}// 用于存储所有满足条件的子数组ArrayList<int[]> ans = new ArrayList<>();// 初始化双指针 l 和 r,以及当前子数组的和 sumint l = 0; // 左指针int r = 1; // 右指针int sum = arr[l]; // 当前子数组的和// 使用滑动窗口算法遍历数组while (l < t) {if (sum > t) {// 如果当前子数组的和大于 t,移动左指针并减去对应的值sum -= arr[l++];} else if (sum == t) {// 如果当前子数组的和等于 t,将其加入结果集ans.add(Arrays.copyOfRange(arr, l, r));// 移动左指针并减去对应的值sum -= arr[l++];// 如果右指针超出数组范围,退出循环if (r >= t) break;// 移动右指针并加上对应的值sum += arr[r++];} else {// 如果当前子数组的和小于 t,移动右指针并加上对应的值sum += arr[r++];}}// 对结果集中的子数组按长度排序ans.sort((a, b) -> a.length - b.length);// 输出所有满足条件的子数组for (int[] an : ans) {StringJoiner sj = new StringJoiner("+"); // 使用 StringJoiner 拼接字符串for (int v : an) {sj.add(v + ""); // 将子数组中的每个元素加入 StringJoiner}System.out.println(t + "=" + sj); // 输出结果}// 输出满足条件的子数组的总数System.out.println("Result:" + ans.size());}
}

详细讲解


1. 输入获取
Scanner sc = new Scanner(System.in); // 创建 Scanner 对象,用于读取输入
getResult(sc.nextInt()); // 调用 getResult 方法,传入输入的整数
  • 功能:
    • 使用 Scanner 从控制台读取一个整数 t
    • 调用 getResult 方法,传入 t 作为参数。

2. 初始化数组
int[] arr = new int[t];
for (int i = 0; i < t; i++) {arr[i] = i + 1;
}
  • 功能:
    • 创建一个长度为 t 的数组 arr
    • 数组内容为 1t 的连续整数。
  • 说明:
    • 例如,如果 t = 5,则 arr = [1, 2, 3, 4, 5]

3. 滑动窗口算法
int l = 0; // 左指针
int r = 1; // 右指针
int sum = arr[l]; // 当前子数组的和while (l < t) {if (sum > t) {sum -= arr[l++]; // 如果和大于 t,移动左指针} else if (sum == t) {ans.add(Arrays.copyOfRange(arr, l, r)); // 如果和等于 t,记录子数组sum -= arr[l++]; // 移动左指针if (r >= t) break; // 如果右指针超出范围,退出循环sum += arr[r++]; // 移动右指针} else {sum += arr[r++]; // 如果和小于 t,移动右指针}
}
  • 功能:
    • 使用滑动窗口算法遍历数组,找到所有和为 t 的连续子数组。
  • 说明:
    • lr 分别表示滑动窗口的左边界和右边界。
    • sum 表示当前窗口内元素的和。
    • 如果 sum > t,移动左指针并减去对应的值。
    • 如果 sum == t,记录当前子数组,并移动左指针。
    • 如果 sum < t,移动右指针并加上对应的值。

4. 结果排序
ans.sort((a, b) -> a.length - b.length);
  • 功能:
    • 对结果集中的子数组按长度从小到大排序。
  • 说明:
    • 使用 sort 方法和 Lambda 表达式实现排序。

5. 输出结果
for (int[] an : ans) {StringJoiner sj = new StringJoiner("+"); // 使用 StringJoiner 拼接字符串for (int v : an) {sj.add(v + ""); // 将子数组中的每个元素加入 StringJoiner}System.out.println(t + "=" + sj); // 输出结果
}System.out.println("Result:" + ans.size()); // 输出满足条件的子数组的总数
  • 功能:
    • 使用 StringJoiner 将子数组拼接成字符串并输出。
    • 输出满足条件的子数组的总数。
  • 说明:
    • StringJoiner 是 Java 8 引入的工具类,用于拼接字符串。
    • 例如,子数组 [2, 3, 4] 会被拼接为 2+3+4

代码运行示例

示例 1:

输入:

5

输出:

5=5
5=2+3
Result:2

解释:

  • 数组 arr = [1, 2, 3, 4, 5]
  • 满足条件的子数组:
    • [5]
    • [2, 3]
  • 总数为 2

示例 2:

输入:

15

输出:

15=15
15=7+8
15=4+5+6
15=1+2+3+4+5
Result:4

解释:

  • 数组 arr = [1, 2, 3, ..., 15]
  • 满足条件的子数组:
    • [15]
    • [7, 8]
    • [4, 5, 6]
    • [1, 2, 3, 4, 5]
  • 总数为 4

总结

  1. 功能:

    • 找到所有和为 t 的连续子数组。
    • 按子数组长度从小到大输出结果。
  2. 优点:

    • 使用滑动窗口算法,时间复杂度为 O(n),效率高。
    • 代码逻辑清晰,易于理解。
  3. 适用场景:

    • 适用于需要查找连续子数组满足特定条件的场景。

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

四、Python算法源码

以下是 Python 代码的详细中文注释和讲解:


Python 代码

# 输入获取
t = int(input())  # 从控制台读取输入的整数 t# 算法入口
def getResult():# 创建一个数组,内容为 1 到 t 的连续整数arr = [i + 1 for i in range(t)]# 用于存储所有满足条件的子数组ans = []# 初始化双指针 l 和 r,以及当前子数组的和 totall = 0  # 左指针r = 1  # 右指针total = arr[l]  # 当前子数组的和# 使用滑动窗口算法遍历数组while l < t:if total > t:# 如果当前子数组的和大于 t,移动左指针并减去对应的值total -= arr[l]l += 1elif total == t:# 如果当前子数组的和等于 t,将其加入结果集ans.append(arr[l:r])# 移动左指针并减去对应的值total -= arr[l]l += 1# 如果右指针超出数组范围,退出循环if r >= t:breakelse:# 移动右指针并加上对应的值total += arr[r]r += 1else:# 如果当前子数组的和小于 t,移动右指针并加上对应的值total += arr[r]r += 1# 对结果集中的子数组按长度排序ans.sort(key=lambda x: len(x))# 输出所有满足条件的子数组for an in ans:print(f"{t}={'+'.join(map(str, an))}")# 输出满足条件的子数组的总数print(f"Result:{len(ans)}")# 算法调用
getResult()

详细讲解


1. 输入获取
t = int(input())  # 从控制台读取输入的整数 t
  • 功能:
    • 使用 input() 函数从控制台读取一行输入。
    • 将输入转换为整数并赋值给变量 t

2. 初始化数组
arr = [i + 1 for i in range(t)]
  • 功能:
    • 创建一个长度为 t 的数组 arr
    • 数组内容为 1t 的连续整数。
  • 说明:
    • 使用列表推导式生成数组。
    • 例如,如果 t = 5,则 arr = [1, 2, 3, 4, 5]

3. 滑动窗口算法
l = 0  # 左指针
r = 1  # 右指针
total = arr[l]  # 当前子数组的和while l < t:if total > t:total -= arr[l]  # 如果和大于 t,移动左指针l += 1elif total == t:ans.append(arr[l:r])  # 如果和等于 t,记录子数组total -= arr[l]  # 移动左指针l += 1if r >= t:  # 如果右指针超出范围,退出循环breakelse:total += arr[r]  # 移动右指针r += 1else:total += arr[r]  # 如果和小于 t,移动右指针r += 1
  • 功能:
    • 使用滑动窗口算法遍历数组,找到所有和为 t 的连续子数组。
  • 说明:
    • lr 分别表示滑动窗口的左边界和右边界。
    • total 表示当前窗口内元素的和。
    • 如果 total > t,移动左指针并减去对应的值。
    • 如果 total == t,记录当前子数组,并移动左指针。
    • 如果 total < t,移动右指针并加上对应的值。

4. 结果排序与输出
ans.sort(key=lambda x: len(x))  # 按子数组长度从小到大排序for an in ans:print(f"{t}={'+'.join(map(str, an))}")  # 输出子数组print(f"Result:{len(ans)}")  # 输出满足条件的子数组的总数
  • 功能:
    • 对结果集中的子数组按长度从小到大排序。
    • 使用 join 将子数组拼接成字符串并输出。
    • 输出满足条件的子数组的总数。
  • 说明:
    • sort(key=lambda x: len(x)) 按子数组长度排序。
    • join 将数组元素用 + 拼接成字符串。
    • 例如,子数组 [2, 3, 4] 会被拼接为 2+3+4

代码运行示例

示例 1:

输入:

5

输出:

5=5
5=2+3
Result:2

解释:

  • 数组 arr = [1, 2, 3, 4, 5]
  • 满足条件的子数组:
    • [5]
    • [2, 3]
  • 总数为 2

示例 2:

输入:

15

输出:

15=15
15=7+8
15=4+5+6
15=1+2+3+4+5
Result:4

解释:

  • 数组 arr = [1, 2, 3, ..., 15]
  • 满足条件的子数组:
    • [15]
    • [7, 8]
    • [4, 5, 6]
    • [1, 2, 3, 4, 5]
  • 总数为 4

总结

  1. 功能:

    • 找到所有和为 t 的连续子数组。
    • 按子数组长度从小到大输出结果。
  2. 优点:

    • 使用滑动窗口算法,时间复杂度为 O(n),效率高。
    • 代码逻辑清晰,易于理解。
  3. 适用场景:

    • 适用于需要查找连续子数组满足特定条件的场景。

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

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

以下是 C++C语言 的代码实现,并附带详细的中文注释和讲解:


C++ 代码

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;// 算法入口
void getResult(int t) {// 创建一个数组,内容为 1 到 t 的连续整数vector<int> arr(t);for (int i = 0; i < t; i++) {arr[i] = i + 1;}// 用于存储所有满足条件的子数组vector<vector<int>> ans;// 初始化双指针 l 和 r,以及当前子数组的和 totalint l = 0; // 左指针int r = 1; // 右指针int total = arr[l]; // 当前子数组的和// 使用滑动窗口算法遍历数组while (l < t) {if (total > t) {// 如果当前子数组的和大于 t,移动左指针并减去对应的值total -= arr[l++];} else if (total == t) {// 如果当前子数组的和等于 t,将其加入结果集vector<int> sub(arr.begin() + l, arr.begin() + r);ans.push_back(sub);// 移动左指针并减去对应的值total -= arr[l++];// 如果右指针超出数组范围,退出循环if (r >= t) break;// 移动右指针并加上对应的值total += arr[r++];} else {// 如果当前子数组的和小于 t,移动右指针并加上对应的值total += arr[r++];}}// 对结果集中的子数组按长度排序sort(ans.begin(), ans.end(), [](const vector<int>& a, const vector<int>& b) {return a.size() < b.size();});// 输出所有满足条件的子数组for (const auto& sub : ans) {cout << t << "=";for (size_t i = 0; i < sub.size(); i++) {if (i > 0) cout << "+";cout << sub[i];}cout << endl;}// 输出满足条件的子数组的总数cout << "Result:" << ans.size() << endl;
}int main() {int t;cin >> t; // 从控制台读取输入的整数 tgetResult(t); // 调用算法函数return 0;
}

C语言 代码

#include <stdio.h>
#include <stdlib.h>// 算法入口
void getResult(int t) {// 创建一个数组,内容为 1 到 t 的连续整数int* arr = (int*)malloc(t * sizeof(int));for (int i = 0; i < t; i++) {arr[i] = i + 1;}// 用于存储所有满足条件的子数组int** ans = (int**)malloc(t * sizeof(int*));int* ansLen = (int*)malloc(t * sizeof(int));int ansCount = 0;// 初始化双指针 l 和 r,以及当前子数组的和 totalint l = 0; // 左指针int r = 1; // 右指针int total = arr[l]; // 当前子数组的和// 使用滑动窗口算法遍历数组while (l < t) {if (total > t) {// 如果当前子数组的和大于 t,移动左指针并减去对应的值total -= arr[l++];} else if (total == t) {// 如果当前子数组的和等于 t,将其加入结果集int* sub = (int*)malloc((r - l) * sizeof(int));for (int i = l; i < r; i++) {sub[i - l] = arr[i];}ans[ansCount] = sub;ansLen[ansCount] = r - l;ansCount++;// 移动左指针并减去对应的值total -= arr[l++];// 如果右指针超出数组范围,退出循环if (r >= t) break;// 移动右指针并加上对应的值total += arr[r++];} else {// 如果当前子数组的和小于 t,移动右指针并加上对应的值total += arr[r++];}}// 对结果集中的子数组按长度排序(冒泡排序)for (int i = 0; i < ansCount - 1; i++) {for (int j = 0; j < ansCount - 1 - i; j++) {if (ansLen[j] > ansLen[j + 1]) {// 交换子数组int* tempSub = ans[j];ans[j] = ans[j + 1];ans[j + 1] = tempSub;// 交换子数组长度int tempLen = ansLen[j];ansLen[j] = ansLen[j + 1];ansLen[j + 1] = tempLen;}}}// 输出所有满足条件的子数组for (int i = 0; i < ansCount; i++) {printf("%d=", t);for (int j = 0; j < ansLen[i]; j++) {if (j > 0) printf("+");printf("%d", ans[i][j]);}printf("\n");}// 输出满足条件的子数组的总数printf("Result:%d\n", ansCount);// 释放动态分配的内存for (int i = 0; i < ansCount; i++) {free(ans[i]);}free(ans);free(ansLen);free(arr);
}int main() {int t;scanf("%d", &t); // 从控制台读取输入的整数 tgetResult(t); // 调用算法函数return 0;
}

详细讲解


1. 输入获取
  • C++:

    int t;
    cin >> t; // 从控制台读取输入的整数 t
    
  • C语言:

    int t;
    scanf("%d", &t); // 从控制台读取输入的整数 t
    
  • 功能:

    • 从控制台读取一个整数 t,表示目标和。

2. 初始化数组
  • C++:

    vector<int> arr(t);
    for (int i = 0; i < t; i++) {arr[i] = i + 1;
    }
    
  • C语言:

    int* arr = (int*)malloc(t * sizeof(int));
    for (int i = 0; i < t; i++) {arr[i] = i + 1;
    }
    
  • 功能:

    • 创建一个长度为 t 的数组,内容为 1t 的连续整数。

3. 滑动窗口算法
  • C++:

    int l = 0; // 左指针
    int r = 1; // 右指针
    int total = arr[l]; // 当前子数组的和while (l < t) {if (total > t) {total -= arr[l++]; // 如果和大于 t,移动左指针} else if (total == t) {vector<int> sub(arr.begin() + l, arr.begin() + r); // 记录子数组ans.push_back(sub);total -= arr[l++]; // 移动左指针if (r >= t) break; // 如果右指针超出范围,退出循环total += arr[r++]; // 移动右指针} else {total += arr[r++]; // 如果和小于 t,移动右指针}
    }
    
  • C语言:

    int l = 0; // 左指针
    int r = 1; // 右指针
    int total = arr[l]; // 当前子数组的和while (l < t) {if (total > t) {total -= arr[l++]; // 如果和大于 t,移动左指针} else if (total == t) {int* sub = (int*)malloc((r - l) * sizeof(int)); // 记录子数组for (int i = l; i < r; i++) {sub[i - l] = arr[i];}ans[ansCount] = sub;ansLen[ansCount] = r - l;ansCount++;total -= arr[l++]; // 移动左指针if (r >= t) break; // 如果右指针超出范围,退出循环total += arr[r++]; // 移动右指针} else {total += arr[r++]; // 如果和小于 t,移动右指针}
    }
    
  • 功能:

    • 使用滑动窗口算法遍历数组,找到所有和为 t 的连续子数组。

4. 结果排序与输出
  • C++:

    sort(ans.begin(), ans.end(), [](const vector<int>& a, const vector<int>& b) {return a.size() < b.size();
    });for (const auto& sub : ans) {cout << t << "=";for (size_t i = 0; i < sub.size(); i++) {if (i > 0) cout << "+";cout << sub[i];}cout << endl;
    }cout << "Result:" << ans.size() << endl;
    
  • C语言:

    for (int i = 0; i < ansCount - 1; i++) {for (int j = 0; j < ansCount - 1 - i; j++) {if (ansLen[j] > ansLen[j + 1]) {int* tempSub = ans[j];ans[j] = ans[j + 1];ans[j + 1] = tempSub;int tempLen = ansLen[j];ansLen[j] = ansLen[j + 1];ansLen[j + 1] = tempLen;}}
    }for (int i = 0; i < ansCount; i++) {printf("%d=", t);for (int j = 0; j < ansLen[i]; j++) {if (j > 0) printf("+");printf("%d", ans[i][j]);}printf("\n");
    }printf("Result:%d\n", ansCount);
    
  • 功能:

    • 对结果集中的子数组按长度从小到大排序。
    • 输出所有满足条件的子数组。
    • 输出满足条件的子数组的总数。

总结

  1. 功能:

    • 找到所有和为 t 的连续子数组。
    • 按子数组长度从小到大输出结果。
  2. 优点:

    • 使用滑动窗口算法,时间复杂度为 O(n),效率高。
    • 代码逻辑清晰,易于理解。
  3. 适用场景:

    • 适用于需要查找连续子数组满足特定条件的场景。

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

六、尾言

什么是华为OD?

华为OD(Outsourcing Developer,外包开发工程师)是华为针对软件开发工程师岗位的一种招聘形式,主要包括笔试、技术面试以及综合面试等环节。尤其在笔试部分,算法题的机试至关重要。

为什么刷题很重要?

  1. 机试是进入技术面的第一关:
    华为OD机试(常被称为机考)主要考察算法和编程能力。只有通过机试,才能进入后续的技术面试环节。

  2. 技术面试需要手撕代码:
    技术一面和二面通常会涉及现场编写代码或算法题。面试官会注重考察候选人的思路清晰度、代码规范性以及解决问题的能力。因此提前刷题、多练习是通过面试的重要保障。

  3. 入职后的可信考试:
    入职华为后,还需要通过“可信考试”。可信考试分为三个等级:

    • 入门级:主要考察基础算法与编程能力。
    • 工作级:更贴近实际业务需求,可能涉及复杂的算法或与工作内容相关的场景题目。
    • 专业级:最高等级,考察深层次的算法以及优化能力,与薪资直接挂钩。

刷题策略与说明:

2024年8月14日之后,华为OD机试的题库转为 E卷,由往年题库(D卷、A卷、B卷、C卷)和全新题目组成。刷题时可以参考以下策略:

  1. 关注历年真题:

    • 题库中的旧题占比较大,建议优先刷历年的A卷、B卷、C卷、D卷题目。
    • 对于每道题目,建议深度理解其解题思路、代码实现,以及相关算法的适用场景。
  2. 适应新题目:

    • E卷中包含全新题目,需要掌握全面的算法知识和一定的灵活应对能力。
    • 建议关注新的刷题平台或交流群,获取最新题目的解析和动态。
  3. 掌握常见算法:
    华为OD考试通常涉及以下算法和数据结构:

    • 排序算法(快速排序、归并排序等)
    • 动态规划(背包问题、最长公共子序列等)
    • 贪心算法
    • 栈、队列、链表的操作
    • 图论(最短路径、最小生成树等)
    • 滑动窗口、双指针算法
  4. 保持编程规范:

    • 注重代码的可读性和注释的清晰度。
    • 熟练使用常见编程语言,如C++、Java、Python等。

如何获取资源?

  1. 官方参考:

    • 华为招聘官网或相关的招聘平台会有一些参考信息。
    • 华为OD的相关公众号可能也会发布相关的刷题资料或学习资源。
  2. 加入刷题社区:

    • 找到可信的刷题交流群,与其他备考的小伙伴交流经验。
    • 关注知名的刷题网站,如LeetCode、牛客网等,这些平台上有许多华为OD的历年真题和解析。
  3. 寻找系统性的教程:

    • 学习一本经典的算法书籍,例如《算法导论》《剑指Offer》《编程之美》等。
    • 完成系统的学习课程,例如数据结构与算法的在线课程。

积极心态与持续努力:

刷题的过程可能会比较枯燥,但它能够显著提升编程能力和算法思维。无论是为了通过华为OD的招聘考试,还是为了未来的职业发展,这些积累都会成为重要的财富。

考试注意细节

  1. 本地编写代码

    • 在本地 IDE(如 VS Code、PyCharm 等)上编写、保存和调试代码,确保逻辑正确后再复制粘贴到考试页面。这样可以减少语法错误,提高代码准确性。
  2. 调整心态,保持冷静

    • 遇到提示不足或实现不确定的问题时,不必慌张,可以采用更简单或更有把握的方法替代,确保思路清晰。
  3. 输入输出完整性

    • 注意训练和考试时都需要编写完整的输入输出代码,尤其是和题目示例保持一致。完成代码后务必及时调试,确保功能符合要求。
  4. 快捷键使用

    • 删除行可用 Ctrl+D,复制、粘贴和撤销分别为 Ctrl+CCtrl+VCtrl+Z,这些可以正常使用。
    • 避免使用 Ctrl+S,以免触发浏览器的保存功能。
  5. 浏览器要求

    • 使用最新版的 Google Chrome 浏览器完成考试,确保摄像头开启并正常工作。考试期间不要切换到其他网站,以免影响考试成绩。
  6. 交卷相关

    • 答题前,务必仔细查看题目示例,避免遗漏要求。
    • 每完成一道题后,点击【保存并调试】按钮,多次保存和调试是允许的,系统会记录得分最高的一次结果。完成所有题目后,点击【提交本题型】按钮。
    • 确保在考试结束前提交试卷,避免因未保存或调试失误而丢分。
  7. 时间和分数安排

    • 总时间:150 分钟;总分:400 分。
    • 试卷结构:2 道一星难度题(每题 100 分),1 道二星难度题(200 分)。及格分为 150 分。合理分配时间,优先完成自己擅长的题目。
  8. 考试环境准备

    • 考试前请备好草稿纸和笔。考试中尽量避免离开座位,确保监控画面正常。
    • 如需上厕所,请提前规划好时间以减少中途离开监控的可能性。
  9. 技术问题处理

    • 如果考试中遇到断电、断网、死机等技术问题,可以关闭浏览器并重新打开试卷链接继续作答。
    • 出现其他问题,请第一时间联系 HR 或监考人员进行反馈。

祝你考试顺利,取得理想成绩!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/2526.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis--21--大Key问题解决方案

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言Redis--20--大Key问题解析 一、如何发现Redis大Key1. 使用Redis命令行工具**MEMORY USAGE****RANDOMKEY****DEBUG OBJECT****SCAN命令****redis-cli 工具&#…

[操作系统] 深入理解约翰·冯·诺伊曼体系

约翰冯诺依曼&#xff08;John von Neumann&#xff0c;1903年12月28日—1957年2月8日&#xff09;&#xff0c;原名诺伊曼亚诺什拉约什&#xff08;Neumann Jnos Lajos&#xff09;&#xff0c;出生于匈牙利的美国籍犹太人数学家&#xff0c;20世纪最重要的数学家之一&#xf…

OpenCV实现Kuwahara滤波

Kuwahara滤波是一种非线性的平滑滤波技术&#xff0c;其基本原理在于通过计算图像模板中邻域内的均值和方差&#xff0c;选择图像灰度值较为均匀的区域的均值来替代模板中心像素的灰度值。以下是Kuwahara滤波的详细原理说明&#xff1a; 一、基本思想 Kuwahara滤波的基本思想…

vue项目引入阿里云svg资源图标

1&#xff1a;生成svg图标 登录阿里云官网 1.1 创建项目组 1.2 从阿里云网站上面获取喜欢的图标加入到已有的项目组 1.3 如果团队有自己的设计师&#xff0c;也可以让设计师上传自己的svg图标到阿里云指定的项目组&#xff1b; 使用的时候&#xff0c;把 资源包下载到本地项…

软件测试 —— 自动化测试(Selenium)

软件测试 —— 自动化测试&#xff08;Selenium&#xff09; 什么是SeleniumPython安装Selenium1.安装webdirver-manager2.安装Selenium 写一个简单用例CSS_SELECTOR和XPATH浏览器快速定位页面元素浏览器的前进&#xff08;forward&#xff09;&#xff0c;后退&#xff08;bac…

新垂直电商的社交传播策略与AI智能名片2+1链动模式S2B2C商城小程序的应用探索

摘要&#xff1a;随着互联网技术的不断进步和电商行业的快速发展&#xff0c;传统电商模式已难以满足消费者日益增长的个性化和多元化需求。新垂直电商在此背景下应运而生&#xff0c;通过精准定位、用户细分以及深度社交传播策略&#xff0c;实现了用户群体的快速裂变与高效营…

Jmeter进行http接口并发测试

目录&#xff1a; 1、Jmeter设置&#xff08;1&#xff09;设置请求并发数&#xff08;2&#xff09;设置请求地址以及参数&#xff08;3&#xff09;添加结果数 2、启动看结果 1、Jmeter设置 &#xff08;1&#xff09;设置请求并发数 &#xff08;2&#xff09;设置请求地址…

有一台服务器可以做哪些很酷的事情

有一台服务器可以做哪些很酷的事情 今天我也来简单分享一下&#xff0c;这几年来&#xff0c;我用云服务器做了哪些有趣的事情。 服务器推荐 1. 个人博客 拥有个人服务器&#xff0c;你可以完全掌控自己的网站或博客。 与使用第三方托管平台相比&#xff0c;你能自由选择网站…

链家房价数据爬虫和机器学习数据可视化预测

完整源码项目包获取→点击文章末尾名片&#xff01;

从网络的角度来看,用户输入网址到网页显示,期间发生了什么?

步骤&#xff08;总体来看&#xff09; 浏览器根据输入网页的URL进行解析&#xff0c;解析出对应的请求方式、URL、端口等&#xff0c;生成HTTP请求报文。浏览器查询缓存&#xff0c;检查缓存是否已经存在该URL的资源&#xff0c;如果缓存命中中直接读取并显示&#xff0c;比如…

MYSQL创建表

1.要求 2.步骤 1.创建数据库: create database mydb6_product;2.使用数据库: use mydb6_product;3.创建employees表&#xff1a; create table employees(id int primary key,name varchar(50) not null, age int not null,gender varchar(10) not null default unknown&…

计算机网络的五层协议

计算机网络的五层协议 ‌计算机网络的五层协议模型包括物理层、数据链路层、网络层、传输层和应用层&#xff0c;每一层都有其特定的功能和相关的协议。‌‌1 ‌物理层‌&#xff1a;负责传输原始的比特流&#xff0c;通过线路&#xff08;有线或无线&#xff09;将数据转换为…

C语言初阶习题【30】字符串左旋

1. 题目描述——字符串左旋 实现一个函数&#xff0c;可以左旋字符串中的k个字符。 例如&#xff1a; ABCD左旋一个字符得到BCDA ABCD左旋两个字符得到CDAB 2. 思路 先思考了下如何把最前面的字符串移到后面。 思路比较简单&#xff0c;就是把第一个字符保存下来&#xf…

ESP8266固件烧录

一、烧录原理 1、引脚布局 2、引脚定义 3、尺寸封装 4、环境要求 5、接线方式 ESP8266系列模块集成了高速GPI0和外围接口&#xff0c;这可能会导致严重的开关噪声。如果某些应用需要高功率和EMI特性&#xff0c;建议在数字I/0线上串联10到100欧姆。这可以在切换电源时抑制过冲…

word-break控制的几种容器换行行为详解

word-break 属性在控制换行行为时需要根据语言判断&#xff0c;对于中文 一个字符就是一个单词&#xff0c;字符换行不影响阅读理解&#xff0c;而对于英文来说&#xff0c;多个连续的字符才会是一个单词&#xff0c;例如中文的 早 英文为 morning。 morning7个字符才算一个单词…

年后找工作需要注意的事项

大家好&#xff01;我是 [数擎 AI]&#xff0c;一位热爱探索新技术的前端开发者&#xff0c;在这里分享前端和 Web3D、AI 技术的干货与实战经验。如果你对技术有热情&#xff0c;欢迎关注我的文章&#xff0c;我们一起成长、进步&#xff01; 开发领域&#xff1a;前端开发 | A…

Flink链接Kafka

一、基于 Flink 的 Kafka 消息生产者 Kafka 生产者的创建与配置&#xff1a; 代码通过 FlinkKafkaProducer 创建 Kafka 生产者&#xff0c;用于向 Kafka 主题发送消息。Flink 执行环境的配置&#xff1a; 配置了 Flink 的检查点机制&#xff0c;确保消息的可靠性&#xff0c;支…

Windows 10 ARM工控主板连接I2S音频芯片

在Windows工控主板应用中&#xff0c;音频功能是一项基本的需求&#xff0c;USB声卡在x86/x64 Windows系统上就可直接免驱使用&#xff0c;但这些USB声卡通常不提供ARM上的Windows系统驱动。本文将介绍如何利用安装在ARM上的Windows工控主板——ESM8400的I2S接口、连接WM8960音…

机器学习实战33-LSTM+随机森林模型在股票价格走势预测与买卖点分类中的应用

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下机器学习实战33-LSTM随机森林模型在股票价格走势预测与买卖点分类中的应用。对于LSTM随机森林模型的融合应用&#xff0c;我们选择股票价格走势预测与买卖点分类作为应用场景。股票市场数据丰富且对投资者具有实际价…

在VS2022中用C++连接MySQL数据库读取数据库乱码问题

1.正确安装mysql 安装之后的配置文件 2.在VS2022中进行相关配置 &#xff08;1&#xff09;右键项目&#xff0c;打开属性 注意是右键项目&#xff0c;不是.cpp文件 &#xff08;2&#xff09;配置属性-> VC目录 -> 包含目录 ->添加头文件路径&#xff08;如图&am…