您的位置:首页 > 产品设计 > UI/UE

Sicily1209. Sequence Sum Possibi题解

2017-06-08 20:10 357 查看

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+j−1)

value=(n+n+j−1)∗j/2

2∗value=(n+n+j−1)∗j

n≥1=>(2n−1)≥1

2∗value≥(j+1)∗j

2∗value≥j2

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

【公式2】:

接下来,继续推导,由上一个推导:

value=n+(n+1)+(n+2)+……+(n+j−1)

value=j∗n+1+2+3+……+j−1

value=j∗n+(1+j−1)∗(j−1)/2

value−(1+j−1)∗(j−1)/2=j∗n

value−j∗(j−1)/2=j∗n

j与n均为正整数,则value−j∗(j−1)/2是j的倍数。

所以,一个循环遍历,直到满足公式1得到的条件:2∗value≥j2,代表这个数value理论上最多可以由这些整数相加而得。

在这个循环下,判断满足题意的条件,即公式2:value−j∗(j−1)/2是j的倍数,每满足一个这个条件的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. 心得

这道题是纯数学题,总感觉算法期末考试有点方= =
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息