1、(图像物体的边界):
这段代码是解决“图像物体的边界”的问题。它提供了一个Java类Main
,其中包含main
方法和getResult
方法,以及一个内部UnionFindSet
类,用于计算像素1代表的物体的边界个数。
main
方法首先读取二维数组的行数m
和列数n
,然后读取二维数组matrix
中的像素值。接着,调用getResult
方法并打印结果。
getResult
方法首先找出所有与像素5相邻的像素1的格子,并将它们作为边界存储在ArrayList
中。然后,使用并查集UnionFindSet
来合并相邻的边界。并查集通过比较边界像素之间的距离来确定它们是否相邻,从而将属于同一个边界的像素合并到同一个集合中。
最后,UnionFindSet
中的count
变量存储了最终的边界数量,并作为结果返回。
2、(英文输入法):
这段代码是解决“英文输入法”的问题。它提供了一个Java类Main
,其中包含main
方法和match
方法,用于实现英文输入法的单词联想功能。
main
方法首先读取一段由英文单词和标点符号组成的语句s
,然后读取一个英文单词前缀pre
。接着,调用match
方法并打印匹配到的单词序列。
match
方法使用正则表达式将输入语句s
分割成单词数组。然后,遍历单词数组,使用TreeSet
来存储所有以pre
为前缀的单词。TreeSet
自动对单词进行排序并避免重复。如果TreeSet
为空,则返回前缀pre
;否则,使用StringJoiner
将排序后的单词序列拼接成字符串并返回。
package OD231;
import java.util.ArrayList;
import java.util.Scanner;
/**
* @description 图像物体的边界
* @level 7
* @score 200
* @url https://hydro.ac/d/HWOD2023/p/OD231
*/
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
private static int m;
private static int n;
private static int[][] matrix;
//坐标偏移
private static int[][] offsets = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}, {-1, -1}, {-1, 1}, {1, -1}, {1, 1}};
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
m = sc.nextInt();
n = sc.nextInt();
matrix = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = sc.nextInt();
}
}
//输出
System.out.println(getResult());
}
public static int getResult() {
//记录所有边界位置
ArrayList<Integer[]> brand = new ArrayList<>();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
//如果是像素5,则扩散
if (matrix[i][j] == 5) {
for (int[] offset : offsets) {
int newI = i + offset[0];
int newJ = j + offset[1];
//如果新位置不越界且为像素1,则是边界
if (newI >= 0 && newI < m && newJ >= 0 && newJ < n && matrix[newI][newJ] == 1) {
brand.add(new Integer[]{newI, newJ});
}
}
}
}
}
int k = brand.size();
//并查集,对所有边界位置进行合并
UnionFindSet ufs = new UnionFindSet(k);
for (int i = 0; i < k; i++) {
int x1 = brand.get(i)[0];
int y1 = brand.get(i)[1];
for (int j = i + 1; j < k; j++) {
int x2 = brand.get(j)[0];
int y2 = brand.get(j)[1];
//如果两个边界像素1的位置横向、纵向距离均小于1,则相邻,合并
//即所有绕格子5的一圈格子1是一个连通集,边界归于1,如果两个5的一圈边界有相邻,则会归于一个
if (Math.abs(x1 - x2) <= 1 && Math.abs(y1 - y2) <= 1) {
//合并一次则边界-1
ufs.union(i, j);
}
}
}
//返回边界数量
return ufs.count;
}
}
//并查集实现
class UnionFindSet {
//根节点
int[] fa;
//边界个数
int count;
public UnionFindSet(int n) {
this.count = n;
this.fa = new int[n];
//初始化根节点是自己
for (int i = 0; i < n; i++) {
fa[i] = i;
}
}
public int find(int x) {
if (x != this.fa[x]) {
this.fa[x] = this.find(this.fa[x]);
return this.fa[x];
}
return x;
}
public void union(int x, int y) {
int x_fa = this.find(x);
int y_fa = this.find(y);
//如果两个不同根,则合并
if (x_fa != y_fa) {
this.fa[x_fa] = y_fa;
//边界-1
this.count--;
}
}
}
package OD232;
import java.util.*;
/**
* @description 英文输入法
* @level 6
*/
/**
* 题目描述
* 主管期望你来实现英文输入法单词联想功能。
* <p>
* 需求如下:
* <p>
* 依据用户输入的单词前缀,从已输入的英文语句中联想出用户想输入的单词,按字典序输出联想到的单词序列,
* 如果联想不到,请输出用户输入的单词前缀。
* 注意:
* <p>
* 英文单词联想时,区分大小写
* 缩略形式如”don’t”,判定为两个单词,”don”和”t”
* 输出的单词序列,不能有重复单词,且只能是英文单词,不能有标点符号
* 输入描述
* 输入为两行。
* <p>
* 首行输入一段由英文单词word和标点符号组成的语句str;
* <p>
* 接下来一行为一个英文单词前缀pre。
* <p>
* 0 < word.length() <= 20
* 0 < str.length <= 10000
* 0 < pre <= 20
* 输出描述
* 输出符合要求的单词序列或单词前缀,存在多个时,单词之间以单个空格分割
*/
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//读取输入
String s = sc.nextLine();
//前缀匹配
String pre = sc.nextLine();
System.out.println(match(pre, s));
}
//根据前缀匹配单词
public static String match(String pre, String str) {
//把单词用非字母分隔开
String[] words = str.split("[^a-zA-Z]");
//存放前缀匹配成功的单词 防重复,TreeSet自动升序
TreeSet<String> list = new TreeSet<>();
for (String word : words) {
if (word.startsWith(pre)) {
list.add(word);
}
}
if (list.isEmpty()) {
return pre;
} else {
StringJoiner result = new StringJoiner(" ");
//按字典排序
list.forEach(result::add);
return result.toString();
}
}
}
标签:输入法,边界,int,13,单词,fa,String,new,刷题
From: https://blog.csdn.net/2401_84585615/article/details/139429523