Question: enter a positive number n, and output all sequences that are n continuous positive numbers.
For example, if the input is 15, the output is as follows: 1 + 2 + 3 + 4 + 5 = 4 + 5 + 6 = 7 + 8 = 15.
3 consecutive sequences: 1-5, 4-6, and
7-8.
Method 1: first, determine that n can be obtained from the sum of several consecutive numbers. Suppose that n can be obtained from M consecutive numbers at most, then M (M + 1) /2 = n this is easy to obtain
M = (sqrt (8n + 1)-1)/2.
According to the question, n must at least be obtained from two consecutive numbers, so the outer loop ranges from 2 to M.
So is there a continuous number or equal to n in each case between 2 and M? Apparently not
Assume that n is obtained from k consecutive numbers, 2 <= k <M, set the k numbers to a1, a2,..., ak.
So
A1 + a2 +... + ak = n
Because it is continuous
A1 + (a1 + 1) + (a1 + 2) +... + (a1 + k-1) = n
That is
K * a1 + k (k-1)/2 = n
In this way, we can obtain
A1 = (n-k (k-1)/2)/k
A1 is the minimum value of the continuous number. It can only meet the requirements when a1 is an integer, that is
(N-k (k-1)/2) % k = 0
.
Print k consecutive incremental values (with a tolerance of 1) For a1.
The Code is as follows:
#include <iostream>#include <cmath>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;}}}
The test code is as follows:
int main(){Sequence1(15);return 0;}
Method 2: Use two numbers small and big to represent the minimum and maximum values of the sequence, respectively. First, initialize small to 1 and big to 2. If the sum of the sequences from small to big is greater than n, we move small to the right, which is equivalent to removing smaller numbers from the sequence. If the sum of the sequences from small to big is less than n, we move big to the right, which is equivalent to adding the next number of big to the sequence. Until small is equal to (1 + n)/2, because the sequence must have at least two numbers.
The method 2 comes from July's blog and directly posts code:
void Sequence2(int n){if(n < 3)return;int nSmall = 1;int nBig = 2;int nMiddle = (n+1)/2;int nSum = nSmall+nBig;while(nSmall < nMiddle){if(nSum == n){for(int i = nSmall; i <= nBig; i++){cout << i << " ";}cout << endl;}while(nSum > n){nSum -= nSmall;nSmall++;if(nSum== n){for(int i = nSmall; i <= nBig; i++){cout << i << " ";}cout << endl;}}nBig++;nSum += nBig;}}
The test code is as follows:
int main(){Sequence2(15);return 0;}
PS: method 1 uses the continuous nature. It is an arithmetic difference series with many mathematical derivation. However, it is better to implement it after understanding it. More importantly, this method is highly efficient when n is large.