HDU-1868-Consecutive sum

                                                              HDU - 1868 - Consecutive sum

 

       链接:http://acm.hdu.edu.cn/showproblem.php?pid=1868

 

 

         题意:给出一个数n,要求你找出有多少种能以连续的数之和等于n的数列,例如15有3种连续的数列之和等于它,1 + 2 + 3 + 4 + 5     =     4 + 5 + 6    =    7 + 8     =   15.

        题目分析,直接的思路就是枚举,但枚举的上下界必须要清楚,否则很容易暴力,加一些剪枝,避免超时。一个数等于一段连续的数列之和,而一段连续的等差数列可以用公式来计算,只需要求出中间的数,就可以知道整个数列的总和,那么我们就自然地分成了两种情况,一种是分成长度为奇数,一种是长度为偶数的数列,

  比如,一个数N,长度n为奇数的数列:等差中项为  a( n+1 ) / 2   =  N / n,   a(n+1)/2= a1 +d*(   (n+1)/2  - 1 );

  推出:  a1= a(n+1)/2- (  ( n+1)/2  - 1  ),所以,整个数列的和为:sum = a1* n + n * (n-1) / 2;

     同理,推出长度为偶数的数列的等差中项为:an/2 = N / n, an/2 = a1+ d * ( n/2 -1 );

  a1 =an/2 - ( n/2 -1 );   数列之和公式同上。

          那么接下来就要分析枚举的上下界了,明显的,枚举的下界为 2,但上界是多少?经过打印枚举的情况,得知数N的枚举上界为N/2(包括N/2),一旦超过这个界限,求出的数列是显然不能够成立的,另外,当求出的a1等于1的时候,这时可以跳出循环,这是一个剪枝。

         附上代码:

/*

ID: D.pan

PROG:HDU-1868

LANG: G++

*/

 

#include<iostream>

#include<cstdio>

#include<iomanip>

#include<cmath>

using namespace std;

 

 

int main()

{

   int n, sum,ans;

   register int i, a;

 

   while( ~scanf( "%d",&n ) )

   {

       for( i=2, ans = 0; i<=n/2; i++ )

       {

           if( i%2 )  a =n/i -( (i+1)/2 - 1 );

           else   a =n/i -( (i/2) - 1 );

           if( a >= 1 )

           {

                sum= a*i + i*(i-1)/2; 

               if( sum== n ) ans ++;

               //printf( " %d/%d = %d  a = %d, sum = %d \n ", n, i, n/i, a, sum );

           }else break;

       }

        printf( "%d\n",ans );

   }

 

   return 0;

}

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值