华为OD机试:特殊的加密算法
题目描述
有一种特殊的加密算法,明文为一段数字串,经过密码本查找转换,生成另一段密文数字串。
规则如下:
1.明文为一段数字串由 0~9 组成
2.密码本为数字 0~9 组成的二维数组
3.需要按明文串的数字顺序在密码本里找到同样的数字串,密码本里的数字串是由相邻的单元格数字组成,上下和左右是相邻的,注意:对角线不相邻,同一个单元格的数字不能重复使用。
4.每一位明文对应密文即为密码本中找到的单元格所在的行和列序号(序号从0开始)组成的两个数宇。
如明文第 i 位 Data[i] 对应密码本单元格为 Book[x][y],则明文第 i 位对应的密文为X Y,X和Y之间用空格隔开。
如果有多条密文,返回字符序最小的密文。
如果密码本无法匹配,返回"error"。
请你设计这个加密程序。
示例1:
密码本:
0 0 2
1 3 4
6 6 4
明文:"3",密文:"1 1"
示例2:
密码本:
0 0 2
1 3 4
6 6 4
明文:"0 3",密文:"0 1 1 1"
示例3:
密码本:
0 0 2 4
1 3 4 6
3 4 1 5
6 6 6 5
明文:"0 0 2 4",密文:"0 0 0 1 0 2 0 3" 和 "0 0 0 1 0 2 1 2",返回字典序最小的"0 0 0 1 0 2 0 3"
明文:"8 2 2 3",密文:"error",密码本中无法匹配
输入描述
第一行输入 1 个正整数 N,代表明文的长度(1 ≤ N ≤ 200)
第二行输入 N 个明文组成的序列 Data[i](0 ≤ Data[i] ≤ 9)
第三行输入 1 个正整数 M,代表密文的长度
接下来 M 行,每行 M 个数,代表密文矩阵
输出描述
输出字典序最小密文,如果无法匹配,输出"error"
用例
题目解析
1.首先,根据输入的明文长度 N,读取明文序列 Data[i]。
2.然后,根据输入的密文长度 M,读取密文矩阵。
3.接下来,遍历明文序列 Data[i],对于每一位数字,在密文矩阵中查找对应的单元格。
4.如果找到了匹配的单元格,记录下该单元格的行和列序号(从0开始),并将它们用空格隔开。
5.如果没有找到匹配的单元格,返回"error"。
6.最后,将所有匹配到的密文按照字典序排序,返回字典序最小的密文。
JS算法源码 const rl = require("readline").createInterface({ input: process.stdin }); var iter = rl[Symbol.asyncIterator](); const readline = async () => (await iter.next()).value; void (async function () { const dataSize = parseInt(await readline()); const datas = (await readline()).split(" ").map(Number); const matrixSize = parseInt(await readline()); const secrets = []; const starts = []; for (let i = 0; i < matrixSize; i++) { secrets.push((await readline()).split(" ").map(Number)); for (let j = 0; j < matrixSize; j++) { if (secrets[i][j] == datas[0]) { starts.push([i, j]); } } } function getResult() { const used = new Array(matrixSize).fill(0).map(() => new Array(matrixSize).fill(false)); for (let [x, y] of starts) { used[x][y] = true; const path = [`${x} ${y}`]; if (dfs(x, y, 1, path, used)) { return path.join(" "); } } return "error"; } const offsets = [ [-1, 0], [0, -1], [0, 1], [1, 0], ]; function dfs(x, y, index, path, used) { if (index == dataSize) { return true; } for (let [offsetX, offsetY] of offsets) { const newX = x + offsetX; const newY = y + offsetY; if ( newX < 0 || newX >= matrixSize || newY < 0 || newY >= matrixSize || used[newX][newY] || secrets[newX][newY] != datas[index] ) { continue; } path.push(`${newX} ${newY}`); used[newX][newY] = true; if (dfs(newX, newY, index + 1, path, used)) { return true; } used[newX][newY] = false; path.pop(); } return false; } console.log(getResult()); })();
Java算法源码 import java.util.ArrayList; import java.util.LinkedList; import java.util.Scanner; public class Main { static int n; static int[] datas; static int m; static int[][] secrets; static final int[][] offsets = {{-1, 0}, {0, -1}, {0, 1}, {1, 0}}; public static void main(String[] args) { Scanner sc = new Scanner(System.in); n = sc.nextInt(); datas = new int[n]; for (int i = 0; i < n; i++) { datas[i] = sc.nextInt(); } ArrayList<Integer> starts = new ArrayList<>(); m = sc.nextInt(); secrets = new int[m][m]; for (int i = 0; i < m; i++) { for (int j = 0; j < m; j++) { secrets[i][j] = sc.nextInt(); if (datas[0] == secrets[i][j]) { starts.add(i * m + j); } } } System.out.println(getResult(starts)); } public static String getResult(ArrayList<Integer> starts) { for (int start : starts) { int x = start / m; int y = start % m; boolean[][] visited = new boolean[m][m]; visited[x][y] = true; LinkedList<String> path = new LinkedList<>(); path.add(x + " " + y); if (dfs(x, y, 1, path, visited)) { return String.join(" ", path); } } return "error"; } public static boolean dfs(int x, int y, int index, LinkedList<String> path, boolean[][] visited) { if (index == n) { return true; } for (int[] offset : offsets) { int newX = x + offset[0]; int newY = y + offset[1]; if (newX < 0 || newX >= m || newY < 0 || newY >= m || visited[newX][newY] || secrets[newX][newY] != datas[index]) { continue; } path.add(newX + " " + newY); visited[newX][newY] = true; if (dfs(newX, newY, index + 1, path, visited)) { return true; } visited[newX][newY] = false; path.removeLast(); } return false; } }
Python算法源码 n = int(input()) datas = list(map(int, input().split())) m = int(input()) secrets = [] starts = [] for i in range(m): secrets.append(list(map(int, input().split()))) for j in range(m): if secrets[i][j] == datas[0]: starts.append((i, j)) offsets = ((-1, 0), (0, -1), (0, 1), (1, 0)) def dfs(x, y, index, path, used): if index == n: return True for offsetX, offsetY in offsets: newX = x + offsetX newY = y + offsetY if newX < 0 or newX >= m or newY < 0 or newY >= m or used[newX][newY] or secrets[newX][newY] != datas[index]: continue path.append(f"{newX} {newY}") used[newX][newY] = True if dfs(newX, newY, index + 1, path, used): return True used[newX][newY] = False path.pop() return False def getResult(): for x, y in starts: used = [[False] * m for _ in range(m)] used[x][y] = True path = [f"{x} {y}"] if dfs(x, y, 1, path, used): return " ".join(path) return "error" print(getResult())
C算法源码 #include <stdio.h> #define MAX_SIZE 201 int n; int datas[MAX_SIZE]; int m; int secrets[MAX_SIZE][MAX_SIZE]; int starts[MAX_SIZE] = {0}; int starts_size = 0; int offsets[4][2] = {{-1, 0}, {0, -1}, {0, 1}, {1, 0}}; int dfs(int x, int y, int index, int path[], int *path_size, int used[][MAX_SIZE]) { if (index == n) { return 1; } for (int i = 0; i < 4; i++) { int newX = x + offsets[i][0]; int newY = y + offsets[i][1]; if (newX < 0 || newX >= m || newY < 0 || newY >= m || used[newX][newY] || secrets[newX][newY] != datas[index]) { continue; } path[(*path_size)++] = newX * m + newY; used[newX][newY] = 1; if (dfs(newX, newY, index + 1, path, path_size, used)) { return 1; } used[newX][newY] = 0; (*path_size)--; } return 0; } void getResult() { for (int i = 0; i < starts_size; i++) { int x = starts[i] / m; int y = starts[i] % m; int used[MAX_SIZE][MAX_SIZE] = {0}; used[x][y] = 1; int path[MAX_SIZE] = {0}; int path_size = 0; path[path_size++] = starts[i]; if (dfs(x, y, 1, path, &path_size, used)) { for (int j = 0; j < path_size; j++) { int pos = path[j]; printf("%d %d", pos / m, pos % m); if (j < path_size - 1) { printf(" "); } } return; } } puts("error"); } int main() { scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d", &datas[i]); } scanf("%d", &m); for (int i = 0; i < m; i++) { for (int j = 0; j < m; j++) { scanf("%d", &secrets[i][j]); if (secrets[i][j] == datas[0]) { starts[starts_size++] = i * m + j; } } } getResult(); return 0; }