数据结构练习(20)和为n连续正数序列

http://zhedahht.blog.163.com/blog/static/25411174200732711051101/

思路:

题目中设置了2个指针:small, big.当他们之间的和大于n时,small往后移动,当小于n时,big往后移动。]最终找出所有满足条件的连续序列。

题目中给了这个思路,但是却没有说明为什么这个思路是可行的,只是直观印象上说:这个是可行的。下面我就自己来分析下为什么可行:

1. 初始small = 1, big = 2.于是可以看出开始的情况下,big会一直往后面移动直到到达一个临界点k使得 sum[small, k] <= n, sum[small, k+1] > n

   如果等于n则输出,并且big继续后移查找下一个序列,直到big = k+1。 到这一步可以得出来一个结论:以small为起始点的区间已经尽其所能了

2. 用数学归纳法的思想来看待这个问题small = 1时,1这个起始点尽其所能的把一些符合条件的区间都输出了,同理可以类比到small = x。

3. 这也就是为什么当sum[small, big] < n时,为什么是big往后面移动,而非small往前面移动,small变小已经没有意义了,因为前面已经输出过了

4. 当sum[small, big] > n 时会不会存在 sum[small + a, big - 1] == n(1 <= a <= big-small-1)呢?

   这种担心是多余的,因为1中已经提到过了k是一个临界点。

   sum[small, big-1] <= n,所以就不会有sum[small+a, big-1] == n这种情况了。

#include <iostream>
using namespace std;


void print_continuous_sequence(int small, int big)
{
    for (int i = small; i <= big; ++i)
        cout << i << " ";
    cout << endl;
}

void find_continuous_sequence(int n)
{
    if (n < 3)
        return;

    int small = 1;
    int big = 2;
    int sum = small + big;

    while (small < big)
    {
        if (sum == n)
            print_continuous_sequence(small, big);

        while (sum > n)
        {
            sum -= small;
            ++small;

            if (sum == n)
                print_continuous_sequence(small, big);
        }
        ++big;
        sum += big;
    }
}

int main()
{
    int n;
    
    while (cin >> n && n > 2)
        find_continuous_sequence(n);

    return 0;
}

 

posted @ 2012-12-14 11:32  kedebug  阅读(190)  评论(0编辑  收藏  举报