您的位置:首页 > 其它

求一段连续整数区间的和

2016-04-11 20:47 113 查看

2058The sum problem

Problem Description

Given a sequence 1,2,3,......N, your job is to calculate all the possible sub-sequences that the sum of the sub-sequence is M.

Input

Input contains multiple test cases. each case contains two integers N, M( 1 <= N, M <= 1000000000).input ends with N = M = 0.

Output

For each test case, print all the possible sub-sequence that its sum is M.The format is show in the sample below.print a blank line after each test case.

Sample Input

20 10

50 30

0 0

Sample Output

[1,4]

[10,10]

[4,8]

[6,9]

[9,11]

[30,30]



数据又是Input contains multiple test cases. each case contains two integers N, M( 1 <= N, M <= 1000000000).input ends with N = M = 0.

10的10次方。数字很大直接枚举肯定是不行的。

一般我们遇到这么的数据时;有两种考虑

1;想办法去开方;

2;找规律;

然而我们这题肯定是要用暴力的,所以就向着第一种方法考虑,想办法去开方,将数据降低;



求在1到n的连续数串中的子串的和是m的情况;

要想到是等差数列,并且使用等差公式去求解;

1~n;可以知道这是等差数列,所以等下不要去一个个去加。因为有等差公式;

等差求和公式;



还有一个关键点就是可以知道和是m的最长子串的长度是好多;

最长就是元素最小的串,可以求出;cd = sqrt((double)(m*2));

然而我们就可以去枚举长度了。

代码

#include<stdio.h>

#include<math.h>

int main()

{

long long int n, m,cd,a1;

while(scanf("%lld %lld",&n, &m) != EOF && (n != 0 || m != 0)){

cd = sqrt((double)(m*2));//子串最长为;1~cd之和大于m;

while(cd){//已知长度已知sum;求两个边界也就是a1和an;

a1 = m/cd-(cd-1)/2;

//计算初值,即a1并且 是整数不需要考虑除法;

if(a1*cd+cd*(cd-1)/2 == m){

printf("[%lld,%lld]\n",a1,a1+cd-1);

}

cd--;

}

printf("\n");

}

return 0 ;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: