行云

行至水穷处,坐看云起时。

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
对于一个正整数,输出它所有可能的连续自然数之和的算式
1+2=3
4+5=9
2+3+4=9
根据题意,有:
s+(s+1)+(s+2)+...+(s+k) = n
(k+1)s + (k+1)k/2 = n
(k+1)(2s+k)=2n
s = (2n/(k+1)-k)/2
因为 s, k都是整数,所以应满足2n%(k+1)==0 && (2n/(k+1)-k)%2==0
void Print(int n, int s, int k)
{
    printf("%d=",n);
    for (int i=s; i<=s+k; i++)
    {
        if (i==s)
            printf("%d", i);
        else
            printf("+%d",i);
    }
    printf("\n");
}
void Decompose(int n)
{
    int up=(int)sqrt((long double)2*n);

    for (int k=1; k<up; k++)
    {
        if ( 2*n%(k+1)==0 && (2*n/(k+1)-k)%2==0 )
        {
            int s=(2*n/(k+1)-k)/2;
            Print(n, s, k);
        }
    }
}

时间复杂度:O((2n)^0.5)

 

void Decompose2(int n)
{
    int start, end, sum;
    start = 1, end = 1, sum=0;
    int up = (n+1)>>2;
    while (end<=up)
    {
        sum += end;
        if (sum == n)
        {
            Print(n, start, end-start);
            sum -= start++;
            end++;
        }
        else if (sum < n)
        {
            end++;
        }
        else
        {
            sum -= end;
            sum -= start++;
        }
    }
}

 

时间复杂度:O(n)  但只用到加减法

 

子序列数目最多的数是哪一个?
子序列最多这一点可以推断出该序列一定是从1开始的,那么就有
(k+1)k/2 <= INT_MAX
k = sqrt(2*INT_MAX);
if ( (k+1)k/2 > INT_MAX)
   k--;
 

 

posted on 2012-05-09 08:39  windflying  阅读(730)  评论(1编辑  收藏  举报