Sicily1209. Sequence Sum Possibi题解

1. 题目描述

Most positive integers may be written as a sum of a sequence of at least two consecutive positive integers. For instance:
6 = 1 + 2 + 3
9 = 5 + 4 = 2 + 3 + 4
but 8 cannot be so written.
Write a program which will compute how many different ways an input number may be written as a sum of a sequence of at least two consecutive positive integers.
【翻译过来】:给了一个数字,将其分解为至少2个连续整数的和的形式,那么一共有多少种方法?

2. 样例

【Input】:
The first line of input will contain the number of problem instances N on a line by itself, (1<=N<=1000) . This will be followed by N lines, one for each problem instance. Each problem line will have the problem number, a single space and the number to be written as a sequence of consecutive positive integers. The second number will be less than 2^31 (so will fit in a 32-bit integer).
【Output】:
The output for each problem instance will be a single line containing the problem number, a single space and the number of ways the input number can be written as a sequence of consecutive positive integers.

Input:
    7 
    1 6 
    2 9 
    3 8 
    4 1800 
    5 987654321 
    6 987654323 
    7 987654325
Output:
    1 1 
    2 2 
    3 0 
    4 8 
    5 17 
    6 1 
    7 23

3. 分析

拿到题目,乍一分析,已为用分治法的思想解决,即:把当前一个大的数字,将其除以2,不断分析规模较小的数字情况,从而加起来。应该用到递归的策略,但是没有找到合适的算法,于是继续分析,发现了数学规律。

【公式1】:
假设需要计算的目标数量为value,一共有以正整数n开始的j个连续的数相加,那么可以得到假设:

value=n+(n+1)+(n+2)++(n+j1)

value=(n+n+j1)j/2

2value=(n+n+j1)j

n1=>(2n1)1

2value(j+1)j

2valuej2

因此我们可以知道,满足条件的k,即连续k个正整数相加等于N,那么k和N满足这样的关系。

【公式2】:
接下来,继续推导,由上一个推导:

value=n+(n+1)+(n+2)++(n+j1)

value=jn+1+2+3++j1

value=jn+(1+j1)(j1)/2

value(1+j1)(j1)/2=jn

valuej(j1)/2=jn

jnvaluej(j1)/2j

所以,一个循环遍历,直到满足公式1得到的条件: 2valuej2 ,代表这个数value理论上最多可以由这些整数相加而得。
在这个循环下,判断满足题意的条件,即公式2: valuej(j1)/2j ,每满足一个这个条件的j值,计数器就记录一次这样的分法(代表此时由j个正整数相加得到),返回计数器值即可。
这里写图片描述

4. 源码

/*
 * main.cpp
 *
 *  Created on: 2017年6月8日
 *  Author: liboyang
 */
#include <iostream>
using namespace std;

int calculate(int value);
int main() {
    int N;
    int number, value;
    cin >> N;
    int counter = N;
    while(counter > 0) {
        counter--;
        cin >> number >> value;
        int result = calculate(value);
        cout << number << " " << result << endl;
    }
    return 0;
}
int calculate(int value) {
    int count = 0;
    for (int j = 2; j * j <= 2*value; j++) {
        if((value - (j-1)*j/2) % j == 0) {
            count++;
        }
    }
    return count;
}

5. 心得

这道题是纯数学题,总感觉算法期末考试有点方= =

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值