The sum problem

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 30916    Accepted Submission(s): 9249


 

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 3

0 0 0

 

Sample Output

[1,4]

[10,10]

 

[4,8]

[6,9]

[9,11]

[30,30]

题意:

    给你从1到N个数,使他的连续子序列和为m,求连续子序列的范围。

思路:

   暴力肯定是不行的,后来想到他是等差数列,公差是1,前n项和为m。

   利用等差数列的求和公式Sn = n*a1 + n*(n-1)/2,带入公差、前n项和得m=a1*n+n*(n-1)/2。

   假设首项是1,我们代入m=a1*n+n*(n-1)/2,则有n(n+1)=2m。
   所以有n*(n+1)=2m>n*n,即n<sqrt(2m); 也就是说项数最多的情况也只有sqrt(2m)。

   首项a1=(m*2/i-i+1)/2 。

   然后枚举等差数列的长度就行了。

代码:

#include<stdio.h>
#include<math.h>
int main()
{
	int n,m,i,a1,k;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		if(n==0&&m==0)
			break;
		k=sqrt((double)(m)*2);
		for(i=k;i>0;i--)
		{
			a1=(m*2/i-i+1)/2;
			if((i*a1+i*(i-1)/2)==m)
			{
				if(a1>0)
					printf("[%d,%d]\n",a1,a1+i-1);
			}	
		}
		printf("\n");
	}
	return 0;
}