编程之美 - 只考加法的算术题

问题描述:
给定一个正整数 N,将N分解为几个(2个以上)连续的自然数的和。是否所有的数都可以做到。

例如 10 = 1 + 2 + 3 + 4。


思路:
以最简单的方式开始思考:
1) N为奇数,奇数可以分解为两个连续的自然数的和。例如 9 = 4+5。
2) 当N为偶数,如果N可以被 3 整除, 假设a = N/3,那么N还可以被分解为 a-1,a,a+1三个数
3) 当N为偶数,如果N是2的x次方,没有任何奇数的因子,那么N是无法分解的。
4) 找到N的奇数因子,  假设 N = A*B  A为奇数 B为偶数:
           -   当A小于B的情况下,分解A得到 a, a+1,那么 a-1, a+2的和也等于A,同样的a-2, a+3
               这样只要找到B组这样的数就可以算出N的。例如 68 = 4 * 17 其中 17 分解为  8 + 9
               那么再分解一组 7 + 10  ....  。 68 =  5 + 6 + 7 + 8 + 9 + 10 + 11 + 12

           -   当A大于B的情况下,可以看做N是由A个B构成,那么以B为中心,向左右分别逐个加减一 A/2次
                就可以得到连续的一个数字序列串,其和为N。例如 40 = 6 + 7 +  8 + 9 + 10。以8为中心,左右
                分别加减2次。

代码:

#include <iostream>
#include <vector>

using namespace std;

void func(int N)
{
    int i = 0, tmp = 0;
    int a = 0;
    vector<int> vec;

    if (N % 2 == 1)
    {
        a = (N-1)/2;
        vec.push_back(a);
        vec.push_back(a+1);
    }
    else if (N%3 == 0)
    {
        a = N / 3;
        vec.push_back(a-1);
        vec.push_back(a);
        vec.push_back(a+1);
    }
    else if (N % 2 == 0)
    {
        for (i = 3; i <= N/2; i+=2)
        {
            if (N % i == 0)
            {
                a = N / i;
                if (a > i)
                {
                    a = N/i - i/2;
                }
                else
                {
                    a = i/2-a+1;
                    i = (N/i)*2;
                }

                while ((a > 0) && (i > 0))
                {
                    vec.push_back(a);
                    a++;
                    i--;
                }
                break;
            }
        }
    }

    if (vec.size() > 0)
    {
        cout << "N="<< N << " >> " << vec[0];
        for (i = 1; (size_t)i < vec.size(); i++)
        {
            cout << " + " << vec[i];
        }
    }
    else
    {
        cout << N << " >> NO RESULT";
    }
    cout << endl << endl;
}

void main()
{
    int i = 0;
    for (i = 2; i< 100; i++)
    {
        func(i);
    }
    cin >> i;
}


你可能感兴趣的:(编程之美 - 只考加法的算术题)