华为OD机试 2023 B卷 找单词(Java JavaScript Python) |
题目描述
给一个字符串和一个二维字符数组,如果该字符串存在于该数组中,则按字符串的字符顺序输出字符串每个字符所在单元格的位置下标字符串,如果找不到返回字符串“N
”。
输入描述
N
指示二维数组在后续输入所占的行数 第2
行到第N+1
行 输入为一个二维大写字符数组,每行字符用半角,分割。N+2
行为待查找的字符串,由大写字符组成。 二维数组的大小为N*N
,0 < N <=100
。 单词长度K
, 0 < K < 1000
。输出描述
N
个字符列下标+”,” +第N
个字符列下标。用例
输入:
4
A,C,C,C
C,D,E,D
B,E,S,S
B,E,S,S
F,E,C,A
输出
0,0,0,1,0,2,1,2,2,2,2,3
说明 ACCESS分别对应二维数组的[0,1][0,1][0,2][1,2][2,2][2,3]下标位置
Java
import java.util.LinkedList;
import java.util.Scanner;
import java.util.StringJoiner;
public class Main {
static int n;
static String[][] matrix;
static String tar;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in).useDelimiter("[,\n]");
n = sc.nextInt();
matrix = new String[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = sc.next();
}
}
tar = sc.next();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
LinkedList<Integer[]> path = new LinkedList<>();
if (dfs(i, j, 0, path)) {
StringJoiner sj = new StringJoiner(",");
for (Integer[] pos : path) {
sj.add(pos[0] + "," + pos[1]);
}
System.out.println(sj.toString());
return;
}
}
}
System.out.println("N");
}
public static boolean dfs(int i, int j, int k, LinkedList<Integer[]> path) {
if (i < 0 || i >= n || j < 0 || j >= n || !tar.substring(k, k + 1).equals(matrix[i][j])) {
return false;
}
path.add(new Integer[] {i, j});
if (path.size() == tar.length()) {
return true;
}
String tmp = matrix[i][j];
matrix[i][j] = null;
boolean res = dfs(i - 1, j, k + 1, path)
|| dfs(i + 1, j, k + 1, path)
|| dfs(i, j - 1, k + 1, path)
|| dfs(i, j + 1, k + 1, path);
if (!res) {
matrix[i][j] = tmp;
path.removeLast();
}
return res;
}
}
Javascript
const readline = require("readline");
// 创建readline接口实例
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
// 存储输入的每一行数据
const lines = [];
// 存储二维数组的大小
let n;
// 监听命令行输入的每一行数据
rl.on("line", (line) => {
// 将每一行数据存入lines数组
lines.push(line);
// 如果输入的是二维数组的大小
if (lines.length === 1) {
n = parseInt(lines[0]);
}
// 如果输入的是二维数组和待查找的字符串
if (n && lines.length === n + 2) {
// 删除lines数组中的第一个元素,即二维数组
lines.shift();
// 将lines数组中的最后一个元素,即待查找的字符串,存入变量str
const str = lines.pop();
// 将lines数组中的其余元素,即二维数组的每一行,按逗号分隔存入二维数组grid
const grid = lines.map((line) => line.split(","));
// 调用findLetter函数,输出结果
console.log(findLetter(grid, n, str));
// 清空lines数组
lines.length = 0;
}
});
// 查找字符串
function findLetter(grid, n, str) {
// 深度优先搜索函数
function dfs(i, j, k, path) {
// 如果越界或者当前位置的字符与待查找的字符不同,返回false
if (i < 0 || i >= n || j < 0 || j >= n || grid[i][j] !== str[k])
return false;
// 将当前位置的下标存入path数组
path.push([i, j]);
// 如果已经找到了待查找的字符串,返回true
if (path.length === str.length) return true;
// 将当前位置的字符置为undefined,表示已经访问过
const tmp = grid[i][j];
grid[i][j] = undefined;
// 按照上下左右的顺序递归查找下一个字符
const res =
dfs(i - 1, j, k + 1, path) ||
dfs(i + 1, j, k + 1, path) ||
dfs(i, j - 1, k + 1, path) ||
dfs(i, j + 1, k + 1, path);
// 如果没有找到,将当前位置的字符还原,并从path数组中删除当前位置的下标
if (!res) {
grid[i][j] = tmp;
path.pop();
}
return res;
}
// 遍历二维数组中的每一个位置,从该位置开始查找待查找的字符串
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
const path = [];
// 如果从该位置开始查找到了待查找的字符串,返回该字符串每个字符所在单元格的位置下标字符串
if (dfs(i, j, 0, path)) {
return path.toString();
}
}
}
// 如果没有找到,返回字符串"N"
return "N";
}
python
from typing import List
from collections import deque
n = int(input())
matrix = []
for i in range(n):
row = input().split(",")
matrix.append(row)
tar = input()
def dfs(i: int, j: int, k: int, path: deque) -> bool:
if i < 0 or i >= n or j < 0 or j >= n or tar[k] != matrix[i][j]:
return False
path.append([i, j])
if len(path) == len(tar):
return True
tmp = matrix[i][j]
matrix[i][j] = None
res = dfs(i - 1, j, k + 1, path) or dfs(i + 1, j, k + 1, path) or dfs(i, j - 1, k + 1, path) or dfs(i, j + 1, k + 1, path)
if not res:
matrix[i][j] = tmp
path.pop()
return res
for i in range(n):
for j in range(n):
path = deque()
if dfs(i, j, 0, path):
res = []
for pos in path:
res.append(str(pos[0]) + "," + str(pos[1]))
print(",".join(res))
exit()
print("N")