1、(可以组成网络的服务器):
这段代码是解决“可以组成网络的服务器”的问题。它提供了一个Java类Main
,其中包含main
方法和getResult
方法,以及一个辅助方法bfs
,用于统计机房中最大的局域网包含的服务器个数。
main
方法首先读取二维数组的行数n
和列数m
,然后读取服务器信息矩阵matrix
。接着,调用getResult
方法并打印结果。
getResult
方法遍历服务器信息矩阵,对于每个服务器(用1表示),使用bfs
方法进行广度优先搜索,以找到最大的局域网。bfs
方法使用一个队列path
来存储待检查的服务器坐标,并通过邻接节点的检查来扩展局域网。每找到一个新服务器,就将其添加到队列中,并将其状态标记为已访问(用0表示)。当队列为空时,表示已经找到了从当前服务器出发的最大局域网。
最后,getResult
方法返回最大的局域网大小。
2、(用连续自然数之和来表达整数):
这段代码是解决“用连续自然数之和来表达整数”的问题。它提供了一个Java类Main
,其中包含main
方法和getResult
方法,用于找出一个整数的所有可能的连续自然数之和的表达式,并打印每种表达式以及它们的个数。
main
方法读取目标整数n
,然后调用getResult
方法并打印所有可能的表达式和最终的表达式个数。
getResult
方法使用滑动窗口技术来找出所有可能的连续自然数序列,这些序列的和等于目标整数n
。通过移动左右指针left
和right
,代码可以找到所有可能的连续序列,并记录它们的起始索引和结束索引。找到所有序列后,使用StringJoiner
来构建每个序列的表达式字符串,并按序列长度升序排列。
最后,getResult
方法返回一个包含所有表达式和最终表达式个数的列表。
package OD233;
import java.util.LinkedList;
import java.util.Scanner;
/**
* @description 可以组成网络的服务器
* @level 6
* @score 200
* @url https://hydro.ac/d/HWOD2023/p/OD233
*/
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static int[][] offsets = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
private static int n;
private static int m;
private static int[][] matrix;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//n行 m列
n = sc.nextInt();
m = sc.nextInt();
//服务器矩阵
matrix = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
matrix[i][j] = sc.nextInt();
}
}
//输出最大局域网的服务器个数
System.out.println(getResult());
}
public static int getResult() {
//记录题解,不断更新较大值
int ans = 0;
//遍历,从每一个起点扩散
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
//如果是1,则进行bfs递归,找到该点最多能扩散的局域网服务器个数
if (matrix[i][j] == 1) {
ans = Math.max(ans, bfs(i, j));
}
}
}
return ans;
}
/**
* 从matrix[i][j]为中心,扩散寻找最多的局域网服务器
* 类似LeetCode200题,岛屿数量 : https://leetcode.cn/problems/number-of-islands/description/
*
* @param i
* @param j
* @return int
* @create 2024/4/3 17:13
*/
public static int bfs(int i, int j) {
//储存找到服务器的坐标
LinkedList<int[]> path = new LinkedList<>();
//初始matrix[i][j]=1,所以初始count=1
matrix[i][j] = 0;
int count = 1;
//添加起点
path.add(new int[]{i, j});
while (path.size() > 0) {
int[] pos = path.removeFirst();
int x = pos[0];
int y = pos[1];
//向四周位移扩散
for (int[] offset : offsets) {
int newX = x + offset[0];
int newY = y + offset[1];
//如果没有越界且是服务器
if (newX >= 0 && newX < n && newY >= 0 && newY < m && matrix[newX][newY] == 1) {
//找到的服务器+1
count++;
//添加到坐标集合
path.add(new int[]{newX, newY});
//把该点设为1,防止回头
matrix[newX][newY] = 0;
}
}
}
//返回最大局域网服务器个数
return count;
}
}
package OD241;
import java.util.*;
/**
* @description 用连续自然数之和来表达整数
* @level 5
* @score 100
*/
/**
* 题目描述
* 一个整数可以由连续的自然数之和来表示。
* <p>
* 给定一个整数,计算该整数有几种连续自然数之和的表达式,且打印出每种表达式
* <p>
* 输入描述
* 一个目标整数T (1 <=T<= 1000)
* <p>
* 输出描述
* 该整数的所有表达式和表达式的个数。
* <p>
* 如果有多种表达式,输出要求为:自然数个数最少的表达式优先输出,每个表达式中按自然数递增的顺序输出,具体的格式参见样例。
* <p>
* 在每个测试数据结束时,输出一行”Result:X”,其中X是最终的表达式个数。
*/
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
//存放结果
ArrayList<String> result = getResult(n);
result.forEach(System.out::println);
}
public static ArrayList<String> getResult(int t) {
//存放结果
ArrayList<String> result = new ArrayList<>();
//创建一个从1-n的数组,使用滑动窗口
int[] arr = new int[t];
for (int i = 0; i < t; i++) {
arr[i] = i + 1;
}
int left = 0;
int right = 1;
//初始化和
int sum = arr[left];
//存放步骤和
ArrayList<int[]> ans = new ArrayList<>();
//当左指针到达数组末尾,结束循环
while (left < t) {
//如果小于n,则左指针移动
if (sum > t) {
sum -= arr[left++];
} else if (sum == t) {
//记录此时的数组元素 包括left 不包含right
ans.add(Arrays.copyOfRange(arr, left, right));
//窗口往右移动
sum -= arr[left++];
//此时right有可能已经到达数组末尾
if (right >= t) {
break;
}
//没有到达边界则往右移动
sum += arr[right++];
} else {
//sum<n 右指针往右移动
sum += arr[right++];
}
}
//排序 按长度升序
ans.sort(Comparator.comparing(a -> a.length));
ans.forEach(a -> {
StringJoiner sj = new StringJoiner("+", t + "=", "");//前缀是n= 连接符是+ 后置是""
Arrays.stream(a).forEach(i -> sj.add(i + ""));
result.add(sj.toString());
});
result.add("Result:" + ans.size());
return result;
}
}