51.和为 n 连续正数序列(数组)。
题目:输入一个正数 n,输出所有和为 n 连续正数序列。例如输入 15,由于 1+2+3+4+5=4+5+6=7+8=15,所以输出 3 个连续序列 1-5、 4- 6 和 7-8。分析:这是网易的一道面试题。
一道简单的小题
/*51.和为 n 连续正数序列(数组)。题目:输入一个正数 n,输出所有和为 n 连续正数序列。例如输入 15,由于 1+2+3+4+5=4+5+6=7+8=15,所以输出 3 个连续序列 1-5、 4- 6 和 7-8。分析:这是网易的一道面试题。*/#include//思路:设连续数字中首个数字为 s 连续数字个数为 l//则这些数字的和为 s*l + l*(l-1)/2void find(int n){ int l; int s; for(s = 1; s * 2 + 1 <= n; s++) //首个数字循环 { for(l = 1; s * l + (l *(l - 1))/2 <= n; l++) { if(s * l + (l *(l - 1))/2 == n) { for(int i = s; i < l + s; i++) { printf("%d ", i); } printf("\n"); } } }}int main(){ find(30000154); return 0;}
网上看到一个思路更好的, 其实没有必要对s循环的,根据l直接算s就可以了。
http://blog.csdn.net/wumuzi520/article/details/8046201
那么
a1+a2+...+ak=n
因为连续,所以
a1+(a1+1)+(a1+2)+...+(a1+k-1)=n
即
k*a1+k(k-1)/2=n
这样就可以求得
a1=(n-k(k-1)/2)/k
a1即为连续数中的最小值,只有在a1为整数的情况下才会符合要求,即
(n-k(k-1)/2)%k==0
时才符合要求。
对符合要求的a1连续打印k个递增(公差为1)的值即可。
#include#include using namespace std;void Sequence1(int n){ int M = (sqrt(8*n+1)-1)/2; for(int i = 2; i <= M; i++) { if((n-(i-1)*i/2)%i == 0) //!!!!!注意学习这里 { int nMin = (n-(i-1)*i/2)/i; for(int j = 0; j < i; j++) { cout << nMin++ << " "; } cout << endl; } }}