华为机试题:拆分自然数

题目描述

一个 0-1000 的整数,拆解为一个(本身)或多个连续自然数的和,按照自然数的个数从少到多输出各个方案 input = solution,方案内的自然数按照从小到大排列

链接:牛客网

code

  • 其实就是数学题:
    • 若一个数n等于连续多个自然数之和,则由等差数列(a1+an)*h/2==n,以及an-a1==n-1,可解得a1=(n*2/h-h+1)/2an=a1+h-1(也就是该连续自然数的第一个数和最后一个数)
    • 因为除法会带来误差,因此验证一下(a1+an)*h==n*2即可
  • (注:算法未经OJ验证
#include <iostream>
#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n;
    while(cin >> n)
    {
        if(n==0){
            printf("0\n");
            continue;
        }

        for(int i=1; i<=n; ++i){//拆成i个自然数之和
            int x = (n*2/i-i+1)/2;
            int y = x+i-1;
            if((x+y)*i==n*2){
                for(int j=x; j<=y; ++j){
                    printf("%d ",j);
                }
                printf("\n");
            }
            else if((x+y)*i>n*2){
                break;
            }
        }
    }
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值