给定一个 R×S
的大写字母矩阵,你的起始位置位于左上角,你可以向上下左右四个方向进行移动,但是不能移出边界,或者移动到曾经经过的字母(左上角字母看作第一个经过的字母)。请问,你最多可以经过几个字母。
输入格式
第一行包含两个整数 R和 S,表示字母矩阵的行和列。
接下来 R 行,每行包含一个长度为 S 的大写字母构成的字符串,共同构成字母矩阵。
输出格式
输出一个整数,表示最多能够经过的字母个数。
数据范围
1≤R,S≤20
输入样例:
3 6
HFDFFB
AJHGDH
DGAGEH
输出样例:
6
解题思路: 解题思路非常清晰,在迷宫问题的基础上,加上一个数组用来储存经过的字母,用来判断新的探索字母是否重复。还需要一个变量用来储存最大值。整体的核心依旧是递归,回溯。
理论成立代码如下:
import java.util.*;
public class Main {
public static int max = 0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
String s = sc.nextLine();//吞换行
char a[][] = new char[n][m];
for(int i = 0; i < n; i ++) {
s = sc.nextLine();
a[i] = s.toCharArray();//存地图
}
char b[] = new char[n*m];
dfs(a, b, 0, 0, 0);//左上角开始
System.out.print(max);
}
public static void dfs(char a[][], char b[], int i, int j, int len) {
if(judge(a, b, i, j, len)) {//退出条件
member(len);
return ;
}
b[len] = a[i][j];
a[i][j] = '1';//标记已经来过
int fx[] = {0, 0, -1, 1};
int fy[] = {-1, 1, 0, 0};//新探索方向
int fxx = 0, fyy = 0;
for(int k = 0; k < 4; k ++) {
fxx = i + fx[k];
fyy = j + fy[k];
if(fxx >= 0 && fxx < a.length && fyy >= 0 && fyy < a[0].length && a[fxx][fyy] != '1') {
char c = a[fxx][fyy];
dfs(a, b, fxx, fyy, len + 1);
a[fxx][fyy] = c;//回溯
}
}
}
public static boolean judge(char a[][], char b[], int i , int j, int len) {
for(int k = 0; k < len; k ++)
if(b[k] == a[i][j]) return true;
return false;
}
public static void member(int len) {
max = Math.max(max, len);
}
}
该问题是一个基于网格的路径搜索问题,从左上角开始,只能向上下左右移动,不能重复经过已走过的字母。使用深度优先搜索(DFS)配合回溯策略,通过一个额外数组记录已访问过的字母,动态维护最大路径长度。当遇到重复字母或者超出边界时,回溯并尝试其他路径。最终得到的最大值即为能经过的最多字母数。
482

被折叠的 条评论
为什么被折叠?



