算法回溯算法

加密算法

2025-10-27  本文已影响0人  何以解君愁

 有一种特殊的加密算法,明文为一段数字串,经过密码本查找转换,生成另一段密文数字串。规则如下:
  1. 明文为一段数字串由0-9组成
  2. 密码本为数字0-9组成的二维数组
  3. 需要按明文串的数字顺序在密码本里找到同样的数字串,密码本里的数字串是由相邻的单元格数字组成,上下和左右是相邻的,注意:对角线不相邻,同一个单元格的数字不能重复使用。
  4. 每一位明文对应密文即为密码本中找到的单元格所在的行和列序号(序号从0开始)组成的两个数字。如明文第i位Data[i]对应密码本单元格为Book[X][Y],则明文第i位对应的密文为X Y,X和Y之间用空格隔开。
 如果有多条密文,返回字符序最小的密文。如果密码本无法匹配,返回"error". 请你设计这个加密程序。

/**
 *
 * {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"
*/

import java.util.*;

public class Main{
    static boolean found = false;
    static List<List<Integer>> res = new ArrayList<>();
    static List<Integer> temp = new ArrayList<>();
    public static void main(String[] args){
        //数据接收
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] data = new int[n];
        for(int i = 0;i < n;i++){
            data[i] = sc.nextInt();
        }
        int m  = sc.nextInt();
        int[][] book = new int[m][m];
        for(int i = 0;i < m;i++){
            for(int j = 0;j < m;j++){
                book[i][j] = sc.nextInt();
            }
        }
        
        //找明文
        boolean[][] check = new boolean[m][m];
        for(int i = 0;i < m;i++){
            for(int j = 0;j < m;j++){
                if(!check[i][j]&&book[i][j] == data[0]){
                    temp.add(i);
                    temp.add(j);
                    check[i][j] = true;
                    backTracking(check,book,data,m,n,0,i,j);
                    check[i][j] = false;
                    temp.remove(temp.size() - 1);
                    temp.remove(temp.size() - 1);
                }
                if(found){
                    Collections.sort(res, (list1, list2) -> {
                        for (int k = 0; k < Math.min(list1.size(),list2.size()); k++) {
                            int cmp = Integer.compare(list1.get(k), list2.get(k));
                            if (cmp != 0) return cmp;
                        }
                        return Integer.compare(list1.size(), list2.size());
                    });
                    List<Integer> ans = res.get(0);
                    for(int k = 0;k < ans.size();k++){
                        System.out.print(ans.get(k) + " ");
                    }
                    return;
                }
            }
        }
        if(!found){
            System.out.print("error");
        }
    }
    
    public static void backTracking(boolean[][] check,int[][] book,int[] data,int m,int n,int index,int i,int j){
        if(index == data.length - 1){
            found = true;
            res.add(new ArrayList<>(temp));
            return;
        }
        
        if(i + 1 < m&&!check[i + 1][j]&&book[i + 1][j] == data[index + 1]){
            temp.add(i+1);
            temp.add(j);
            check[i + 1][j] = true;
            backTracking(check,book,data,m,n,index+1,i+1,j);
            check[i + 1][j] = false;        
            temp.remove(temp.size() - 1);
            temp.remove(temp.size() - 1);
        }
        if(j + 1 < m&&!check[i][j + 1]&&book[i][j + 1] == data[index + 1]){
            temp.add(i);
            temp.add(j+1);
            check[i][j+1] = true;
            backTracking(check,book,data,m,n,index+1,i,j+1);
            check[i][j+1] = false;        
            temp.remove(temp.size() - 1);
            temp.remove(temp.size() - 1);
        }
        if(i - 1 >= 0&&!check[i - 1][j]&&book[i - 1][j] == data[index + 1]){
            temp.add(i-1);
            temp.add(j);
            check[i - 1][j] = true;
            backTracking(check,book,data,m,n,index+1,i - 1,j);
            check[i - 1][j] = false;        
            temp.remove(temp.size() - 1);
            temp.remove(temp.size() - 1);
        }
        if(j - 1 >= 0&&!check[i][j - 1]&&book[i][j - 1] == data[index + 1]){
            temp.add(i);
            temp.add(j - 1);
            check[i][j - 1] = true;
            backTracking(check,book,data,m,n,index+1,i,j - 1);
            check[i][j - 1] = false;        
            temp.remove(temp.size() - 1);
            temp.remove(temp.size() - 1);
        }
    }
}
上一篇 下一篇

猜你喜欢

热点阅读