public class Test{
/**
*
* 总体思路为根据求和公式,得到一个二次函数。求解二次函数判断当前位置是否满足条件
* 所以只需要一次遍历就可以搞定
*
* 1:根据等比数列的求和公式得出 其中
* a1 表示数列第一个元素
* an 表示数列最后一个元素
* n表示数列的个数 并且 n = an - a1 + 1
* 最终求和公式为:(a1 + an)n / 2 = a
*
* 2:将 n 带入原公式 就可以得出如下表达式 (下面的 "^" 不是异或运算,表示乘方)
* a 表示和,即传入的次数
* i 表示通过for循环的索引值,表示数列的第一个元素)
* n 表示数列的最后一个值,通过运算 直接求出
*
* 用上述符号替代原公式,得到如下公式
* (i + n)(n - i + 1) / 2 = a
*
* 拆分之后,就变成了一个二次函数
* 2 * a = n ^ 2 - n * i + n + n * i - i ^ 2 + i
* 2 * a = n ^ 2 + n - i ^ 2 + i
* 根据二次函数的求根公式求解 n 的值 (-b + sqrt(b ^ 2 -4ac)) / 2a 得出 n 的值
* n ^ 2 + n - i ^ 2 + i - 2 * a = 0
* b ^ 2 -4ac 的值如下
* 1 - 4 (i - 2 * a - i ^ 2);
*
* n 的两个解如下
* (-1 + Math.sqrt(1 - 4 (i - 2 * a - i * i))) / 2
* (-1 - Math.sqrt(1 - 4 (i - 2 * a - i * i))) / 2
*
* 判断以下得到的 n 是否为一个整数(得到的结果为一个double类型) 为整数则说明从当前位置(i)出发 有连续的整数 和为 a
*
*/
public static int get(int a) {
// 记录返回结果
int res = 0;
for (int i = 0; i
// b1 即为 ”n“ 对应的索引下标,只不过使用double表示
double b1 = (-1 + Math.sqrt(1 - 4 * (i - 2 * a - i * i))) / 2;
// 因为这个解为负数,所以不考虑
//double b2 = (-1 - Math.sqrt(1 - 4 * (i - 2 * a - i * i))) / 2;
System.out.println(b1);
// 判断解是否为一个整数
if (b1 - (long) b1 == 0) {
res++;
}
}
return res;
}
}