杭电oj2058

The sum problem
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 32853 Accepted Submission(s): 9775

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]

解题思路:用两个for循环,时间复杂度为n²,由于数字过大,运行会超时。
下面介绍AC的方法:解题围绕等差数列求和公式进行。(首项 * 末项)*项数/2.
这里我们用 i(数字i的值) 表示首项, j表示项数, i+j-1得到末项。
所以我们的任务就是要找到 i 和 j的值。
写公式:(i+(i+j-1)) * j / 2 = m(公式1)
由公式1得: i = ((2 * m)/j - j + 1)/2; (这一步为了求得i的值)
为了进一步较少循环的次数:由公式1得:j * j + 2 * i * j - j = 2m; 且i大于等于1;则2 * i * j - j >0;
所以j < sqrt(2 * m);

#include 
#include 

int main()
{
	int m, n, i, j, len;
	while(scanf("%d%d", &n, &m) && (m+n))
	{
		len = sqrt(2.0*m);
		for(j = len; j >= 1;j --)
		{
			i = ((2*m)/j-j+1)/2;
			if((i+(i+j-1))*j/2 == m)   //当i和j同时满足时等式才成立
				printf("[%d,%d]\n", i, i+j-1);
		}
		printf("\n");
	}
}

你可能感兴趣的:(C语言学习,acm)