应用题_将一数字分解连续整数和

来源:互联网 发布:华为商城源码 编辑:程序博客网 时间:2024/05/30 04:30

应用题_将一数字分解连续整数和


<<<百度编程竞赛题目??>>>
题目描述:一个正整数有可能可以被表示为n(n>=2)个连续正整数之和,如:
    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

评分标准:程序输出结果是否正确。

 


算法分析
设可行数列为 A = { a1 , a2 , a3 , ... }
根据题意知,A 是一组 d=1 的等差序列,
没 A 有 s 个元素,
则数列和 SA = s * a1 + s(s-1)/2 = n
显然 a1 的取值范围为 ( 1<=a1<=n/2 )

问题就是成了判断一元二次方程有无整数解,
其中 a1 , n 为常数,s 为所求变量。

s = ( -(2*a1-1) + sqrt( (2*a1-1)^2 + 8*n ) ) / 2

 


////////////////////////////////////////////////////////////
// 源程序
// pro.cpp : 定义控制台应用程序的入口点。
// 10:13 2005-10-22
//
#include "stdafx.h"
#include "math.h"
#include "conio.h"

bool findSeq( unsigned int n )
{
 bool flag = false;

 unsigned int a1;
 unsigned int half = n / 2;
 for( a1 = 1 ; a1 <= half ; a1++ )
 {
  double s = 0;
  s = 4 * a1 * a1 - 4 * a1 + 1 + 8 * n;
  s = sqrt( s );
  s = s + (-2) * (double)a1 + 1;
  s /= 2;
  unsigned int t = s;
  if( fabs( s - (double)t ) < 1e-6 )
  {
   flag = true;
   for( int i = 0 ; i < t ; i++ )
    printf( "%3d" , a1+i );
   printf( "/n" );
  }
 }
 if( !flag )
  printf( "NONE/n" );
 return true;
}

int _tmain(int argc, _TCHAR* argv[])
{
 findSeq( 16 );

 getch();
 return 0;
}
////////////////////////////////////////////////////////////

原创粉丝点击