问题来源:http://acm.hdu.edu.cn/showproblem.php?pid=2058
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]
问题解读:
有一个序列1,2,3,……n,我们输入n和m,n表示连续等差序列的最大数,m表示我们要求的和值,我们需要列举出序列中符合连续几项的和等于m的情况。
问题分析:
首先,我们可以发现,这是一个等差序列,我们可以使用等差序列的求和公式,(a表示首项,b表示末项,i表示项数)
由于
可得
得出
因此,我的第一次提交的代码如下:
不过,超时了。
我想,应该是i=n这一步的影响。如果,我把n输入一个很大的数,而m很小的话,循环还在一直持续着,但后面的内容都是不可能输出的。因此,接下来要做的就是减少循环的次数。
可以从入手。因为
,化简可得
,所以可得
。i的范围也就缩小了,这样循环的次数也就减少了。
修改后的代码如下:
import java.util.Scanner;
public class Test_2058 {
public static void main (String args[]) {
Scanner in = new Scanner(System.in);
while(in.hasNext()) {
Long n = in.nextLong();
Long m = in.nextLong();
if(n == 0 && m == 0)
break;
long a;
long b;
for(long i=(long)Math.sqrt(2*m);i>0;i--) {
a = m / i - (i-1) / 2;
b = a + i - 1;
if((a+b)*i == 2*m && a > 0 && b > 0)
System.out.println("["+a+","+b+"]");
}
System.out.println();
}
}
}
小结:
在循环时,要尽量地优化,减少不必要的循环,提高时间效率。