【编程题目】和为 n 连续正数序列

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 <stdio.h>

//思路:设连续数字中首个数字为 s 连续数字个数为 l
//则这些数字的和为 s*l + l*(l-1)/2
void 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 <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;
        }
    }
}

 

posted @ 2014-08-08 15:13  匡子语  阅读(529)  评论(0编辑  收藏  举报