一、ISBN号码

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.next();
        int res = 0,start = 1;;
        for (int i = 0; i < str.length()-1; i++) {
            if(str.charAt(i)=='-') continue;
            res += Integer.parseInt(Character.toString(str.charAt(i)))*start;
            start++;
        }
        res %= 11;
        String result  = new StringBuilder(str).deleteCharAt(str.length()-1).toString();
        if(res == 10){
            result = result + "X";
        }else {
            result = result + res ;
        }
        if(result.equals(str)){
            System.out.println("Right");
        }else {
            System.out.println(result);
        }
    }
}

思路:

1.从控制台读取一个字符串 str(例如 "0-306-40615-7")。

2.计算该字符串中除最后一个字符外所有数字(跳过连字符 -)的加权和,权重从 1 开始依次递增。

3.用加权和对 11 取模,得到一个新的校验码(10 用 X 表示)。将原字符串去掉最后一个字符,再拼接新校验码,形成新字符串。

4.比较新字符串与原字符串,若相同输出 "Right",否则输出新字符串(即修正后的结果)。

1.从控制台读取一个字符串 str

Scanner sc = new Scanner(System.in);
String str = sc.next();            // 读取一行输入,遇空格或换行结束
int res = 0, start = 1;            // res: 加权和, start: 当前权重

2.计算该字符串中除最后一个字符外所有数字(跳过连字符 -)的加权和,权重从 1 开始依次递增。

方法一:

遍历字符串前length-1个字符,排除最后一个校验位

for (int i = 0; i < str.length()-1; i++) {
    if(str.charAt(i)=='-') continue;          // 跳过连字符
    res += Integer.parseInt(Character.toString(str.charAt(i))) * start;
    start++;
}

遇到连接符‘-’时用continue跳过

str.char(i)  -->从字符串中取出索引  i 处的字符

Integer.parseInt(Character.toString(str.charAt(i)))

先把字符串中取出来的字符转化为String类型,用Character.toString( )

再把String类型转化为Int类型,取到整数,用Interger.parseInt( )

Interger.parseInt( )是把字符串转化为int类型整数的静态方法

方法二:

int num = str.charAt(i) - '0';
res += num * start;

这个方法可以直接把字符串变成整数,比上面的方法更简洁清晰

3.用加权和对 11 取模,得到一个新的校验码(10 用 X 表示)。

res %= 11;                         // 模 11 得到新校验码数值
String result = new StringBuilder(str).deleteCharAt(str.length()-1).toString();
// 去掉原字符串最后一个字符(原校验位)
if(res == 10){
    result = result + "X";
} else {
    result = result + res;
}

String result = new StringBuilder(str).deleteCharAt(str.length()-1).toString();

(1)由于需要修改字符串,所以借用StringBuilder方法

new StringBuiler(str),创建一个StringBuilder类型的对象,用原字符串str初始化其内容。

(2)然后调用  StringBuilder  的  deleteCharAt (int index)方法,删掉最后一个字符

(3)把修改后StringBuiler对象转换回不可变的String对象,赋值给 result

将原字符串去掉最后一个字符,再拼接新校验码,形成新字符串。

4.比较新字符串与原字符串,若相同输出 "Right",否则输出新字符串(即修正后的结果)。

if(result.equals(str)){
    System.out.println("Right");
} else {
    System.out.println(result);
}

二、kotori和迷宫

考点:深度优先搜索

import java.util.*;

public class Main {
    static class Pair {
        int x, y;
        Pair(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 读取迷宫大小
        int n = in.nextInt();
        int m = in.nextInt();
        char[][] a = new char[n + 1][m + 1];
        int beginx = 0, beginy = 0;

        for (int i = 1; i <= n; i++) {
            String line = in.next();
            for (int j = 1; j <= m; j++) {
                a[i][j] = line.charAt(j - 1);
                if (a[i][j] == 'k') {
                    beginx = i;
                    beginy = j;
                }
            }
        }

        // BFS
        int[][] dist = new int[n + 1][m + 1];
        for (int i = 1; i <= n; i++) {
            Arrays.fill(dist[i], 1, m + 1, -1);
        }
        int[] dx = {0, 1, 0, -1};
        int[] dy = {-1, 0, 1, 0};
        Queue<Pair> q = new LinkedList<>();
        q.offer(new Pair(beginx, beginy));
        dist[beginx][beginy] = 0;

        while (!q.isEmpty()) {
            Pair cur = q.poll();
            int x1 = cur.x, y1 = cur.y;
            for (int i = 0; i < 4; i++) {
                int x2 = x1 + dx[i];
                int y2 = y1 + dy[i];
                if (x2 >= 1 && x2 <= n && y2 >= 1 && y2 <= m &&
                    a[x2][y2] != '*' && dist[x2][y2] == -1) {
                    dist[x2][y2] = dist[x1][y1] + 1;
                    if (a[x2][y2] == 'e') {
                        continue; // 出口不加入队列,不继续扩展
                    }
                    q.offer(new Pair(x2, y2));
                }
            }
        }

        // 统计出口
        int cnt = 0;
        int minDist = Integer.MAX_VALUE;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (a[i][j] == 'e' && dist[i][j] != -1) {
                    cnt++;
                    if (dist[i][j] < minDist) {
                        minDist = dist[i][j];
                    }
                }
            }
        }

        if (cnt == 0) {
            System.out.println(-1);
        } else {
            System.out.println(cnt + " " + minDist);
        }
    }
}

1.输入处理

int n = in.nextInt();
int m = in.nextInt();
char[][] a = new char[n + 1][m + 1];
int beginx = 0, beginy = 0;

for (int i = 1; i <= n; i++) {
    String line = in.next();
    for (int j = 1; j <= m; j++) {
        a[i][j] = line.charAt(j - 1);
        if (a[i][j] == 'k') {
            beginx = i;
            beginy = j;
        }
    }
}
char[n + 1][m + 1]为什么要n+1和m+1?
用空间代替清晰性。为了使用 1‑based 索引(行号和列号从 1 开始计数),而不是默认的 0‑based。

String line = in.next();读取当前按行的字符串。先按字符串读取,再用charAt(int index)方法读取每一个数

if (a[i][j] == 'k') {
            beginx = i;
            beginy = j;
}读取格子的起点并标记

二、BFS最短路径搜素

int[][] dist = new int[n + 1][m + 1];
for (int i = 1; i <= n; i++) {
    Arrays.fill(dist[i], 1, m + 1, -1);
}
int[] dx = {0, 1, 0, -1};
int[] dy = {-1, 0, 1, 0};
Queue<Pair> q = new LinkedList<>();
q.offer(new Pair(beginx, beginy));
dist[beginx][beginy] = 0;
  • dist 数组记录每个格子从起点出发的最短步数,初始化为 -1 表示未访问。

  • Arrays.fill(dist[i], 1, m+1, -1) 填充索引 [1, m] 范围内的元素(起始索引包含,结束索引不包含)。

  • 方向数组 dx, dy 对应左、下、右、上四个方向(顺序无关紧要)。

  • 使用队列进行 BFS,起点入队,距离设为 0。

核心 BFS 循环

while (!q.isEmpty()) {
    Pair cur = q.poll();
    int x1 = cur.x, y1 = cur.y;
    for (int i = 0; i < 4; i++) {
        int x2 = x1 + dx[i];
        int y2 = y1 + dy[i];
        if (x2 >= 1 && x2 <= n && y2 >= 1 && y2 <= m &&
            a[x2][y2] != '*' && dist[x2][y2] == -1) {
            dist[x2][y2] = dist[x1][y1] + 1;
            if (a[x2][y2] == 'e') {
                continue; // 出口不加入队列,不继续扩展
            }
            q.offer(new Pair(x2, y2));
        }
    }
}
  • 每次弹出队首节点 (x1, y1),遍历四个相邻格子。

  • 如果相邻格子合法(在边界内)、不是墙 '*'、且未访问过(dist == -1),则:

    • 更新其距离为当前距离 +1。

    • 关键:若该格子是出口 'e',则不将其加入队列(通过 continue 跳过入队操作)。
      原因:出口是目标点,不需要再从出口继续向外扩展,这能提高效率,且避免无意义的搜索。

    • 否则,将格子入队以便继续 BFS。

  • BFS 的特点保证第一次到达某个格子时,dist 记录的就是最短步数。


四、统计结果

int cnt = 0;
int minDist = Integer.MAX_VALUE;
for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
        if (a[i][j] == 'e' && dist[i][j] != -1) {
            cnt++;
            if (dist[i][j] < minDist) {
                minDist = dist[i][j];
            }
        }
    }
}
  • 遍历整个迷宫,找出所有出口(a[i][j] == 'e')且 dist 不为 -1(即可达)的格子。

  • 累加可达出口数量 cnt,并更新最小距离 minDist


五、输出

if (cnt == 0) {
    System.out.println(-1);
} else {
    System.out.println(cnt + " " + minDist);
}
  • 若无出口可达,输出 -1

  • 否则输出 cnt 和 minDist,中间用空格分隔。


六、代码优点

  1. BFS 正确性:对于无权图,BFS 保证第一次访问即最短路径。

  2. 边界处理简洁:数组下标从 1 开始,避免了多处 -1 判断。

  3. 出口不入队优化:减少不必要的扩展,尤其当出口较多时能提升效率。

  4. 距离与访问标记合一dist 数组既记录距离,又充当 visited 标记。

  5. 输入鲁棒:使用 in.next() 逐行读取字符串,正确处理换行。

更多推荐