每天一到算法练习题1 -- 一个正整数有可能可以被表示为 n(>=2) 个连续正整数之和

说明

此题在多种场合出现,包括百度程序之星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");
}






你可能感兴趣的:(c,算法,百度,System,input)