题目:
输入一个正数n,输出所有和为n连续正数序列。例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以输出3个连续序列1-5、4-6和7-8。
继续做些题目,看到这是网易面试题,于是又认认真真自己思考着做了。
解决:
结果一定是2个相连的数、3个相连的数、4个、5个等等。那么可以把这个数n除以i(i为2,3,4...代表相连的数的个数),得到的这些相邻的数的大概平均值,如当 n = 15、i = 2 时,n / i = 7,这代表如果有两个相邻的数的和是15,那么它们的大概平均值是7;i = 3 时,n / i = 5,代表三个连续的数的大概平均值是5,那么这三个数是4,5,6。大概平均值是因为整数除引起的。所以可以由相连数的个数得到这些数的大概平均值,从而可以得到这么多个相连的数,判断它们的和是否满足,不满足再看下一个相邻数的个数,直到相连数的第一个到了1。
代码及结果:
1 #include <iostream> 2 3 using std::cin; 4 using std::cout; 5 using std::endl; 6 7 void hs(int n) 8 { 9 if (n <= 1) 10 return; 11 12 for (int ii = 2;; ii++) // ii 代表结果由几个数字相加 13 { 14 int divisionRes = n / ii; //相当于 ii 个数的平均数 15 int thisSum = 0; 16 int pS = divisionRes, pE = divisionRes; //两个指针 17 int pLS; //最左边的一个数 18 19 if (ii % 2) //ii 是奇数 20 { 21 thisSum += pS; 22 pLS = divisionRes - (ii / 2); 23 } 24 else //ii 是偶数 25 { 26 pE++; 27 thisSum += (pS + pE); 28 pLS = divisionRes - (ii / 2) + 1; 29 } 30 31 if (pLS < 1) 32 break; 33 34 pS--, pE++; //上面的判断已经计算了最中心的了 35 while (pS >= pLS) 36 { 37 thisSum += (pE + pS); 38 pS--, pE++; 39 } 40 41 if (thisSum == n) 42 { 43 pS++, pE--; 44 while (pS <= pE) 45 cout << pS++ << " "; 46 cout << endl; 47 } 48 } 49 } 50 51 int main(void) 52 { 53 int t = 160; 54 while (t--) 55 { 56 int n = rand() % 1000; 57 cout << n << endl; 58 hs(n); 59 cout << "----------------------------------------------------------------------------- "; 60 } 61 cin.get(); 62 }
注意:
1:奇数个相连的数和偶数个相连的数的统一。
2:相连的数边界的处理。