数据结构练习(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; }
kedebug
Department of Computer Science and Engineering,
Shanghai Jiao Tong University
E-mail: kedebug0@gmail.com
GitHub: http://github.com/kedebug
-------------------------------------------------------