题目描述
一个整数可以由连续的自然数之和来表示。
给定一个整数,计算该整数有几种连续自然数之和的表达式,且打印出每种表达式
输入描述
一个目标整数T (1 <=T<= 1000)
输出描述
该整数的所有表达式和表达式的个数。
如果有多种表达式,输出要求为:自然数个数最少的表达式优先输出,每个表达式中按自然数递增的顺序输出,具体的格式参见样例。
在每个测试数据结束时,输出一行”Result:X”,其中X是最终的表达式个数。
用例1
输入
9
输出
9=9
9=4+5
9=2+3+4
Result:3
说明
整数 9 有三种表示方法,第1个表达式只有1个自然数,最先输出,
第2个表达式有2个自然数,第2次序输出,
第3个表达式有3个自然数,最后输出。
每个表达式中的自然数都是按递增次序输出的。
数字与符号之间无空格
用例2
输入
10
输出
10=10
10=1+2+3+4
Result:2
package odjava.分100;
import java.util.*;
/**
* 滑动窗口
* 输入
* 9
* 输出
* 9=9
* 9=4+5
* 9=2+3+4
* Result:3
*/
public class 用连续自然数之和来表达整数_64 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
getResult(sc.nextInt());
}
// 计算整数 number 的所有连续自然数之和表达式并输出
public static void getResult(int number) {
int[] arr = new int[number];
for (int i = 0; i < number; i++) {
arr[i] = i + 1; // 初始化数组 arr 为连续自然数
}
ArrayList<int[]> ans = new ArrayList<>(); // 存储结果的列表
int left = 0;
int right = 1;
int sum = arr[left]; // 初始化当前和为 arr[left]
while (left < number) {
if (sum > number) {
sum -= arr[left++]; // 若当前和大于 number,则左边界向右移动,减去左边界值
} else if (sum == number) {
ans.add(Arrays.copyOfRange(arr, left, right)); // 若当前和等于 number,则将当前子数组添加到结果列表中
sum -= arr[left++]; // 左边界向右移动,减去左边界值
if (right >= number) {
break; // 若右边界超过数组边界,则退出循环
}
sum += arr[right++]; // 右边界向右移动,加上右边界值
} else {
sum += arr[right++]; // 若当前和小于 number,则右边界向右移动,加上右边界值
}
}
// ans.sort((a, b) -> a.length - b.length); // 按子数组长度升序排序
ans.sort(Comparator.comparingInt(a -> a.length));
// 输出结果
for (int[] an : ans) {
StringJoiner sj = new StringJoiner("+");
for (int v : an) {
sj.add(v + "");
}
System.out.println(number + "=" + sj);
}
System.out.println("Result:" + ans.size()); // 输出结果数量
}
}