此题在多种场合出现,包括百度程序之星2005年初赛。
难度:2星。
主要涉及的思想:递推。
题目描述:一个正整数有可能可以被表示为 n(>=2) 个连续正整数之和
15
15=1+2+3+4+5
15=4+5+6
15=7+8
请编写程序,根据输入的任何一个正整数,找出符合这种要求的所有连续正整数序列。
输入数据:一个正整数,以命令行参数的形式提供给程序。
输出数据:在标准输出上打印出符合题目描述的全部正整数序列,每行一个序列,每个序列都从该序列的最小正整数开始、以从小到大的顺序打印。如果结果有多个序列,按各序列的最小正整数的大小从小到大打印各序列。此外,序列不允许重复,序列内的整数用一个空格分隔。如果没有符合要求的序列,输出 “NONE” 。
例如,对于 15 ,其输出结果是:
1 2 3 4 5
4 5 6
7 8
对于16 ,其输出结果是:
NONE
思想:设置两个指针i, j。用sum(i, j)表示i + (i+1) + ... + j的值。我们要找出 sum == n时的i和j。
一直 j <= n/2+1. i >=1。
递推公式如下:
当 sum(i,j) ==n 时,得到一个个结果。
当 sum (i, j) < n 时,说明还不够,j往后一位变成j+1,此时sum = sum + j +1。
当 sum(i,j) > n时,说明过了,此时i往后移一位,变成i+1。此时 sum = sum -i。
直到 i >=j 或者 j > n/2+1。
代码如下,注打印信息,没有完全按照题目要求,这个随意。在DEV c++上编译运行成功。
#include<iostream> using namespace std; //find the sequential sum for an input number void printResult(int sum, int begin, int end) { cout << sum << "="; for(int i = begin; i < end; i++) { cout << i << "+"; } cout << end << ";" << endl; } int findAndPrint(int n) { int mid = n/2 + 1; int i = 1; int j = i+1; int partSum = i + j; int count = 0; while(i <= j && j <= mid) { if(partSum == n) { count ++; printResult(n, i, j); partSum -= i; i++; } else if(partSum < n) { j++; partSum += j; } else if (partSum > n) { partSum -= i; i++; } } return count; } int main() { int count = findAndPrint(16); cout << "total find " << count << endl; system("pause"); }