字母 AcWing (JAVA)

该问题是一个基于网格的路径搜索问题,从左上角开始,只能向上下左右移动,不能重复经过已走过的字母。使用深度优先搜索(DFS)配合回溯策略,通过一个额外数组记录已访问过的字母,动态维护最大路径长度。当遇到重复字母或者超出边界时,回溯并尝试其他路径。最终得到的最大值即为能经过的最多字母数。

给定一个 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);
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值