超时代码:思路易想到,但是数据量太大
package com.demo3;
import java.util.Scanner;
/*
* 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.
*/
public class HDU_oj2058 {
public static void main(String[] args) {
Scanner sn = new Scanner(System.in);
long n,m,sum,start,end=0;
while(sn.hasNext()) {
n = sn.nextLong();
m = sn.nextLong();
if(n == 0 && m == 0) {
break;
}
for(long i = 1;i <= n;i++) {
sum = 0;
start = i; //首先从i开始
if(start <= m) { //如果刚好遍历到这个值等于m
end = start;
while(sum < m) { //遍历序列
sum += end;
end++;
}
if(sum == m) {
end = end-1;
System.out.println("[" + start + "," + end +"]");
} else {
continue;
}
}
}
System.out.println();
}
sn.close();
}
}
正确代码如下:数据规模太大,需要整数分解,思路见代码注释
package com.demo3;
import java.util.Scanner;
/*
* 整数分解:(首项+末项)*项数 /2
*/
public class HDU_oj2058_1 {
public static void main(String[] args) {
Scanner sn = new Scanner(System.in);
int len, temp;
while (sn.hasNext()) {
int N = sn.nextInt();
int M = sn.nextInt();
if(N == 0 && M == 0)
break;
/*
* len = (int) Math.sqrt(M * 2.0);
* 思路分析:
* 等差数列,公差为1,假设首项是a,项数是b; 等差数列求和公式:(a1+an)*n / 2;
* 则 M = (a + (a+b-1))*b /2;
* 所以:2M = (a + (a+b-1))*b = (2a + b - 1)*b
* 且:a>=1
* 所以:2M >= b^2
* 即:项数b <= 根号2M
*/
len = (int) Math.sqrt(M * 2.0);
/*
* temp = M - (i * i + i) / 2;
* 思路分析:
* M = (a + (a+b-1))*b /2;
* 2M = 2ab + b^2 -b
* 2ab = 2M - b^2 + b
* ab = (2M - b^2 + b) / 2 = M - (b^2 - b)/2;
* 令temp = ab;
* temp / a = b 项数
* temp / b = a 首项
*/
for (int i = len; i >= 1; --i) { //这里的i就是思路中表示的b(项数)
temp = M - (i * i - i) / 2;
if (temp % i == 0) { //首项为整数
// 首项:(temp / i)
// 末项:(temp / i + i- 1) 首项+项数-1
System.out.println("[" + (temp / i) + "," + (temp / i + i - 1) + "]");
}
}
System.out.println();
}
sn.close();
}
}