问题一:写一个程序,对于一个64位正整数,输出它所有可能的连续自然数之和的算式。
这里我们不妨假设组成这个和式的数字有n项,且从k开始,需要分解的数字为x那么根据等差数列求和公式可以简单得到:
x=(k+k+1+...+k+n−1)=(k+k+n−1)∗n/2=k∗n+(n−1)∗n/2
由于k大于等于1,可以解得
n(n+1)<=x∗2
在程序中,我们由此确定n的上线:
n<=2x−−√
这里我们可以简单得到,如果x为偶数,那么不能分解成两项之和,如果是奇数,则一定可以分解成两项之和,于是我们通过判断输入值的奇偶性来得到n的起始值是3还是2。这里我们可以简单得到代码:
class Solution{
public:
vector<vector<int>> DisassembleNumber(int num)
{
int k, n,tmp;
int flag = !(num & 1);
int len = sqrt((double)(num*2.0));
vector<vector<int>> ret;
for (n = 2 + flag; n <= len; n++)
{
tmp = num - n*(n - 1) / 2;
if (tmp%n == 0)
{
k = tmp / n;
ret.push_back(toNumberString(k, n));
}
}
return ret;
}
private:
vector<int> toNumberString(int k, int n)
{
vector<int> ret;
while (ret.size() != n)
{
ret.push_back(k);
k++;
}
return ret;
}
};
以上就是第一个问题的简单解决。
那么问题2:不能写成这样的数字有什么规律呢?
问题3:在64位正整数范围内,子序列数目最多的数是哪一个?能不能用数学知识推导出来?