华为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;
}

全部评论

相关推荐

一上来寿司代码,lc130被围绕的区域我没做过这个但是做过岛屿数量,所以先是很粗暴的开四个for循环先把边缘统统排除,再统计核心区面试官问能不能写的更优雅一些,让我试一试考虑把dfs函数带个返回值,想明白了之后需要判断dfs的这个岛会不会在边上,在边上就返回1不在返回0,写的是int和乘法,面试官说把int换成bool乘法换成和运算就更完美了会什么编程语言,我说C和C++是主要的,js会一点点(简历写有前端项目,没有C++项目)问我js和C++有哪些区别,我答了一些原型链&nbsp;弱类型&nbsp;垃圾回收&nbsp;,面试官帮我补充了一个js是动态语言问我了解过吗,我就说部分语句写错了是不影响整体的,不像C++编译器说你错,整个文件直接失败一个函数都执行不了(没了解过,胡说八道的,但是python是这样的)。他笑了笑就给我解释这个动态是什么意思两个场景题,第一个答得完美,另一个一开始答错,答了两遍面试官都说让我好好想想,第三次整明白了还把原理说明白了,他说很好接下来问了很多C++和C的底层,很多都是涉及到指针和内存相关的,除了有一个完全没答上来(我在一本正经的胡说八道),其他题目回答良好或者优秀反问我先问他您是随机分配的还是说假设我入职了我就一定到您的这个组去,他确认如果我入职了他就是leader,顺着这个问题还回答了这个组是做什么业务的,有哪些技术栈,C++&nbsp;TypeScript&nbsp;安卓&nbsp;iOS都有,又顺着给我学习建议,既然我喜欢写C++那就可以多看看底层,有机会看看编译原理和CSAPP。我就商业互吹您一次把我想问的说完了(我确实想问他学习建议来着)最后他还给我面试评价说随机应变能力强,他可能把我推下一轮面试去(是他主动说的,记住任何时候都不要向面试官问面试评价)更新,不到24小时收到下一轮面试邀请了(经评论区的佬说明还不是面委),看来这位面试官对我的面评应该是一个不错的,但是下一轮面试要到节后去了节后更新&nbsp;,三面纯KPI面,面试官说自己是Java的,问了几个java问题,我说了我不会Java,然后随便扯了个场景题,第一遍没答好想追问那个场景其他特点的,还没等我反应过来,就把我挂了
腾讯二面594人在聊 查看3道真题和解析
点赞 评论 收藏
分享
头像
07-01 12:59
已编辑
蚂蚁集团_Java后端
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务