华为OD机试 2025A卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。
一、题目描述
一个整数可以由连续的自然数之和来表示给定一个整数,计算该整数有几种连续自然数之和的表达式,且打印出每种表达式。
二、输入描述
一个目标整数T(1<=T<=1000)
三、输出描述
该整数的所有表达式和表达式的个数。如果有多种表达式,输出要求为:
自然数个数最少的表达式优先输出
每个表达式中按自然数递增的顺序输出,具体的格式参见样例。
在每个测试数据结束时,输出一行”Result:X”,其中X是最终的表达式个数。
用例:
1、输入
9
2、输出
9=9
9=4+5
9=2+3+4
Result:3
四、解题思路
- 输入目标整数T;
- 定义存储符合要求的数组集合arrList;
- 定义sum,计算窗口之和;
- 如果窗口之和大于目标t,left指针右移;
- 如果窗口之和等于目标t,表示获取到合适窗口;
- left指针右移,继续探索新窗口;
- 如果right指针超出范围,break;
- right指针右移,继续探索新窗口;
- 如果窗口之和小于目标t,right指针右移;
- 按照自然数个数升序排序,自然数个数最少的表达式优先输出;
- 按照指定格式输出。
六、Python算法源码
# 导入所需模块
import sys
def main():
# 读取输入
t = int(sys.stdin.readline())
# 构造自然数列表,从1到t
arr = list(range(1, t + 1))
# 符合要求的列表集合
arr_list = []
left = 0
right = 1
# 计算窗口之和
sum_window = arr[left]
# 滑动窗口
while left < t and right <= t:
if sum_window > t:
# 如果窗口之和大于目标t,左指针右移
sum_window -= arr[left]
left += 1
elif sum_window == t:
# 如果窗口之和等于目标t,添加当前窗口
arr_list.append(arr[left:right])
# 左指针右移,继续探索新窗口
sum_window -= arr[left]
left += 1
else:
# 如果窗口之和小于目标t,右指针右移
if right < t:
sum_window += arr[right]
right += 1
else:
# 右指针已到末尾,左指针右移
sum_window -= arr[left]
left += 1
# 按照自然数个数升序排序
arr_list.sort(key=lambda x: len(x))
# 按照指定格式输出
for array in arr_list:
expression = "+".join(map(str, array))
print(f"{t}={expression}")
print(f"Result:{len(arr_list)}")
if __name__ == "__main__":
main()
七、JavaScript算法源码
// 导入读取模块
const readline = require('readline');
function main() {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let input = [];
rl.on('line', (line) => {
input.push(line);
});
rl.on('close', () => {
// 读取输入
const t = parseInt(input[0]);
// 构造自然数数组,从1到t
const arr = Array.from({length: t}, (_, i) => i + 1);
// 符合要求的数组集合
let arrList = [];
let left = 0;
let right = 1;
// 计算窗口之和
let sum = arr[left];
// 滑动窗口
while (left < t && right <= t) {
if (sum > t) {
// 如果窗口之和大于目标t,左指针右移
sum -= arr[left++];
} else if (sum === t) {
// 如果窗口之和等于目标t,添加当前窗口
arrList.push(arr.slice(left, right));
// 左指针右移,继续探索新窗口
sum -= arr[left++];
} else {
// 如果窗口之和小于目标t,右指针右移
if (right < t) {
sum += arr[right++];
} else {
// 右指针已到末尾,左指针右移
sum -= arr[left++];
}
}
}
// 按照自然数个数升序排序
arrList.sort((a, b) => a.length - b.length);
// 按照指定格式输出
arrList.forEach(array => {
const expression = array.join('+');
console.log(`${t}=${expression}`);
});
console.log(`Result:${arrList.length}`);
});
}
main();
八、C算法源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义一个结构体存储数组及其长度
typedef struct {
int *array;
int length;
} Sequence;
int main() {
int t;
// 读取输入
scanf("%d", &t);
// 构造自然数数组,从1到t
int *arr = (int*)malloc(t * sizeof(int));
for(int i = 0; i < t; i++) {
arr[i] = i + 1;
}
// 符合要求的数组集合,假设最多有t种
Sequence *arrList = (Sequence*)malloc(t * sizeof(Sequence));
int count = 0;
int left = 0;
int right = 1;
int sum = arr[left];
// 滑动窗口
while(left < t && right <= t) {
if(sum > t) {
// 如果窗口之和大于目标t,左指针右移
sum -= arr[left++];
}
else if(sum == t) {
// 如果窗口之和等于目标t,添加当前窗口
int len = right - left;
arrList[count].array = (int*)malloc(len * sizeof(int));
for(int i = 0; i < len; i++) {
arrList[count].array[i] = arr[left + i];
}
arrList[count].length = len;
count++;
// 左指针右移,继续探索新窗口
sum -= arr[left++];
}
else {
// 如果窗口之和小于目标t,右指针右移
if(right < t) {
sum += arr[right++];
}
else {
// 右指针已到末尾,左指针右移
sum -= arr[left++];
}
}
}
// 按照自然数个数升序排序(简单选择排序)
for(int i = 0; i < count -1; i++) {
for(int j = i +1; j < count; j++) {
if(arrList[i].length > arrList[j].length) {
Sequence temp = arrList[i];
arrList[i] = arrList[j];
arrList[j] = temp;
}
}
}
// 按照指定格式输出
for(int i = 0; i < count; i++) {
printf("%d=", t);
for(int j = 0; j < arrList[i].length; j++) {
printf("%d", arrList[i].array[j]);
if(j != arrList[i].length -1){
printf("+");
}
}
printf("\n");
}
printf("Result:%d\n", count);
// 释放内存
for(int i = 0; i < count; i++) {
free(arrList[i].array);
}
free(arrList);
free(arr);
return 0;
}
九、C++算法源码
#include <bits/stdc++.h>
using namespace std;
int main(){
int t;
// 读取输入
cin >> t;
// 构造自然数数组,从1到t
vector<int> arr(t);
for(int i =0; i < t; i++) arr[i] = i+1;
// 符合要求的数组集合
vector<vector<int>> arrList;
int left =0, right =1;
int sum = arr[left];
// 滑动窗口
while(left < t && right <= t){
if(sum > t){
// 如果窗口之和大于目标t,左指针右移
sum -= arr[left++];
}
else if(sum == t){
// 如果窗口之和等于目标t,添加当前窗口
vector<int> current(arr.begin()+left, arr.begin()+right);
arrList.push_back(current);
// 左指针右移,继续探索新窗口
sum -= arr[left++];
}
else{
// 如果窗口之和小于目标t,右指针右移
if(right < t){
sum += arr[right++];
}
else{
// 右指针已到末尾,左指针右移
sum -= arr[left++];
}
}
}
// 按照自然数个数升序排序
sort(arrList.begin(), arrList.end(), [&](const vector<int> &a, const vector<int> &b) -> bool{
return a.size() < b.size();
});
// 按照指定格式输出
for(auto &array : arrList){
cout << t << "=";
for(int i=0; i < array.size(); i++){
cout << array[i];
if(i != array.size()-1) cout << "+";
}
cout << "\n";
}
cout << "Result:" << arrList.size() << "\n";
return 0;
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2025 A卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。