题目:
有一种特殊的加密算法,明文为一段数字串,经过密码本查找转换,生成另一段密文数字串。
规则如下
1•明文为一段数字串由0-9组成
2.密码本为数字0-9组成的二维数组
3•需要按明文串的数字顺序在密码本里找到同样的数字串,密码本里的数字串是由相邻的单元
格数字组成,上下和左右是相邻的,注意:对角线不相邻,同一个单元格的数字不能重复使
用。
4 •每一位明文对应密文即为密码本中找到的单元格所在的行和列序号(序号从0开始)组成的两个
数字。如明文第位Data[i]对应密码本单元格为Book[x][y],则明文第i位对应的密文为XY, X和
Y之间用空格隔开
如果有多条密文,返回字符序最小的密文。如果密码本无法匹配,返回"error"
请你设计这个加密程序
示例1:
密码本
[0 0 2]
[1 3 4]
[6 6 4]
明文:3,密文."1 1”
示例2:
示例2:
密码本:
0 0 2
1 3 4
6 6 4
明文:"0 3”密文:0 1 1 1”
输入描述
第一行输入1个正整数N,代表明文的长度(1 <= N <= 200)
第二行输入N个明文数字组成的序列Data[i](整数:0<= Data[i] <= 9)
第三行1个正整数M,代表密文的长度接下来M行,每行M个数,代表密文矩阵
输出描述
输出字典序最小密文•如果无法匹配,输出"error
示例1:
输入:
2
0 3
3
0 0 2
1 3 4
6 6 4
输出:
0 1 1 1
示例2:
输入:
2
0 5
3
0 0 2
1 3 4
6 6 4
输出:
error
题解:
要在矩阵中找到连续的坐标位置,那么这种搜索就直接使用DFS搜索算法。这个题要注意有多条密文时候返回字符序最小的密文。所有搜索的时候顺序应该是左->上->下->右(因为排列是先x坐标后y坐标),这样找到第一个符合条件的数据就是最小的密文。
如果不按这个顺序的话,那么就需要将多条密文序列进行排序,找出最小结果了(这个逻辑比较好理解)
这个题只有100分,但感觉还是有点难度的
代码
import java.util.*;public class DFS1 {private static String result = "";// private static String sumResult = "";public static void main(String[] args) {Scanner sc = new Scanner(System.in);int num = Integer.valueOf(sc.nextLine());String nums[] =sc.nextLine().split(" ");int value[] = new int[num];for(int i =0;i<nums.length;i++){value[i] = Integer.valueOf(nums[i]);}int m = Integer.valueOf(sc.nextLine());int arr[][] = new int[m][m];for(int i=0;i<m;i++){String arrs[] = sc.nextLine().split(" ");for(int j =0;j<m;j++){arr[i][j] = Integer.valueOf(arrs[j]);}}int directions[][] = {{-1,0},{0,-1},{0,1},{1,0}}; // 搜索顺序 很重要,这样第一个结果就是最小值了boolean hasdata = false;// Map<String,List<String>> resultMap = new HashMap<>();// List<String> resultValues = new ArrayList<>();for(int i=0;i<m;i++){for(int j=0;j<m;j++){if(arr[i][j] == value[0]){result = i+" "+j;// sumResult = String.valueOf(i)+String.valueOf(j);// System.out.println("first is i"+i+"j "+j);if(dfs(directions,arr,i,j,value,1,m)){hasdata = true;// List<String> stringList = new ArrayList<>();// stringList.add(result);// resultMap.put(sumResult,stringList);// resultValues.add(sumResult);break;}}}if(hasdata){break;}}if(hasdata){
// Collections.sort(resultValues);
// System.out.println(resultMap.get(resultValues.get(0)).get(0));System.out.println(result);}else {System.out.println("error");}}public static boolean dfs(int[][] directions, int[][] arrs, int x, int y, int[] value, int index, int m) {int presentValue = value[index];int i = 0;while (i < 4) {if(i>=4){break;}int newX = x + directions[i][0];int newY = y + directions[i][1];
// if (newX >= 0 && newX < m && newY >= 0 && newY < m) {
// System.out.println("newX " + newX + " newY " + newY + " arrs[newX][newY " + arrs[newX][newY] + "presentValue " + presentValue);
// }if (newX >= 0 && newX < m && newY >= 0 && newY < m && arrs[newX][newY] == presentValue) {result += " " + newX + " " + newY;// sumResult = sumResult + String.valueOf(newX) + String.valueOf(newY);if (index == value.length - 1) {return true;}index++;return dfs(directions, arrs, newX, newY, value, index, m);}if (newX < 0 || newX >= m || newY < 0 || newY >= m || arrs[newX][newY] != presentValue) {i++;continue;}}return false;}}
方法2:不考虑搜索顺序,按照结果集排序,找出最小的
import java.util.*;public class DFS1 {private static String result = "";private static String sumResult = "";public static void main(String[] args) {Scanner sc = new Scanner(System.in);int num = Integer.valueOf(sc.nextLine());String nums[] =sc.nextLine().split(" ");int value[] = new int[num];for(int i =0;i<nums.length;i++){value[i] = Integer.valueOf(nums[i]);}int m = Integer.valueOf(sc.nextLine());int arr[][] = new int[m][m];for(int i=0;i<m;i++){String arrs[] = sc.nextLine().split(" ");for(int j =0;j<m;j++){arr[i][j] = Integer.valueOf(arrs[j]);}}// int directions[][] = {{-1,0},{0,-1},{0,1},{1,0}}; // 搜索顺序 很重要,这样第一个结果就是最小值了int directions[][] = {{-1,0},{0,-1},{1,0},{0,1}}; // 搜索顺序 很重要,这样第一个结果就是最小值了boolean hasdata = false;Map<String,List<String>> resultMap = new HashMap<>();List<String> resultValues = new ArrayList<>();for(int i=0;i<m;i++){for(int j=0;j<m;j++){if(arr[i][j] == value[0]){result = i+" "+j;sumResult = String.valueOf(i)+String.valueOf(j);// System.out.println("first is i"+i+"j "+j);if(dfs(directions,arr,i,j,value,1,m)){hasdata = true;List<String> stringList = new ArrayList<>();stringList.add(result);resultMap.put(sumResult,stringList);resultValues.add(sumResult);break;}}}
// if(hasdata){
// break;
// }}if(hasdata){Collections.sort(resultValues);System.out.println(resultMap.get(resultValues.get(0)).get(0));// System.out.println(result);}else {System.out.println("error");}}public static boolean dfs(int[][] directions, int[][] arrs, int x, int y, int[] value, int index, int m) {int presentValue = value[index];int i = 0;while (i < 4) {if(i>=4){break;}int newX = x + directions[i][0];int newY = y + directions[i][1];
// if (newX >= 0 && newX < m && newY >= 0 && newY < m) {
// System.out.println("newX " + newX + " newY " + newY + " arrs[newX][newY " + arrs[newX][newY] + "presentValue " + presentValue);
// }if (newX >= 0 && newX < m && newY >= 0 && newY < m && arrs[newX][newY] == presentValue) {result += " " + newX + " " + newY;sumResult = sumResult + String.valueOf(newX) + String.valueOf(newY);if (index == value.length - 1) {return true;}index++;return dfs(directions, arrs, newX, newY, value, index, m);}if (newX < 0 || newX >= m || newY < 0 || newY >= m || arrs[newX][newY] != presentValue) {i++;continue;}}return false;}}
验证结果: