一个正整数分解为几个连续的正整数之和

题目: 给定你一个数字 如:15 15可分解为 7+8 4+5+6 1+2+3+4+5 再如: 8 8不可分解为任何连续的正整数之和 所以输出NONE 此题就是给定一个数字如果这个数字可以分解为几个连续的正整数之和那么就输出所有的形式,如果不能就输出NONE

今天这道题困扰了我好久,最后发现,一开始求和的时候算错了。
输入数n,设置起始位置i,再遍历连续正整数的长度k,由公式计算出 sum = i + (i+1) + … + (i+k) = (k+1) * (2*i + k) / 2;
而我一开始算出来为k* (2*i + k+1) / 2;
原因是我这样计算的:
(i+k)*(i+k+1)/2-i*(i+1)/2
而实际上应该是:
(i+k)*(i+k+1)/2-(i-1)*i/2
下面是我最后成功解决这个问题的思路和代码:

#include<iostream>  
using namespace std;
/*首先
这道题目可以用到数学中最基础的等差公式的方式:设给定的数字为S 
S = a1 + a2 + a3 + a4....
S = a1 + a1 + 1 + a1 + 2 + a1 + 3....设一共有i个
S = (a1 + a1 + i - 1) * i /2

首先我们讨论那些数不能分解为上面的形式
a1 + a1 + i - 1   和 i  这两个数肯定要么一个为偶数要么一个为奇数(自己脑补)
所以他们成绩除2得出的数肯定得有奇数因子,而2^n不可能有奇数因子,所以不能被整除。*/
int IsTwo(int n)
{
    return (n&(n - 1)) == 0 ? 1 : 0;
}
/*用此函数
n如果为2的n次方那么他的二进制表示肯定是第一位为1后面都是0
n - 1恰好是最后一个是1其余多是0所以n&(n - 1)肯定等于0
所以在这里我们可以采用位运算&来判定*/
int main()
{
    int num, sum = 0;
    cout << "请输入一个正整数:" << endl;
    cin >> num;
    if (IsTwo(num)) cout << "NONE" << endl;
    else {
        for (int i = 1; i <= num / 2; i++) 
        //两个大于num/2的整数之和肯定大于num,故只需循环到num/2  
        {
            for (int k = 1;; k++)          //k从1开始,不是从i开始  
            {
                sum = (k + 1) * (2 * i + k) / 2;
                if (sum > num)
                    break;
                if (sum == num)
                {
                    cout << num << "=";
                    for (int j = 0; j < k; j++)
                        cout << i + j << "+";    //输出i+j  
                    cout << i + k << endl;
                }
            }

        }
    }
    return 0;
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值