华为OD机试 - 用连续自然数之和来表达整数 - 滑动窗口(Python/JS/C/C++ 2025 A卷 100分)

在这里插入图片描述

华为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

四、解题思路

  1. 输入目标整数T;
  2. 定义存储符合要求的数组集合arrList;
  3. 定义sum,计算窗口之和;
  4. 如果窗口之和大于目标t,left指针右移;
  5. 如果窗口之和等于目标t,表示获取到合适窗口;
    • left指针右移,继续探索新窗口;
    • 如果right指针超出范围,break;
    • right指针右移,继续探索新窗口;
  6. 如果窗口之和小于目标t,right指针右移;
  7. 按照自然数个数升序排序,自然数个数最少的表达式优先输出;
  8. 按照指定格式输出。

六、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算法的适用场景,发现新题目,随时更新。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值