题目链接:https://www.lanqiao.cn/problems/89/learning/
    题目描述:
    image.png
    数据规模:
    image.png

    题目思路:数据规模较小,可以用深搜暴力求解,其实这个就是 dfs 迷宫问题的变形,我们从迷宫的入口(左上角)开始搜索,直到走到迷宫的出口(右上角)停止。不过在这里会多了几个约束,比如每次走到一个新格子,需要向 北面的墙西面的墙 射箭,只有当走到迷宫时,在两面的墙射箭的数量等于题目给定的值,才算解决了这个问题。还有一个问题就是在这一过程我们要不断维护一个路径(从入口到出口)。

    写代码遇到的几个细节:

    1. 在搜索到匹配的值时,直接就输出答案,不然在dfs退栈时会把完整的答案破坏,除非在回溯时加上判断标志。
    2. 记得剪枝操作,如果在某一面的墙的箭 > 大于题目给定的数值,那么就没必要搜索下去,因为接着搜索下去只会让值更大。
    3. 在遇到迷宫出口时,不需要对其做额外的回溯处理,因为这个已经包含在了dfs的主体中了。
    1. import java.util.ArrayList;
    2. import java.util.List;
    3. import java.util.Scanner;
    4. // 1:无需package
    5. // 2: 类名必须Main, 不可修改
    6. public class Main {
    7. static int n;
    8. static int[][] map;
    9. static int[] north1, west1;
    10. static int[] north2, west2;
    11. static boolean[][] visited;
    12. static int[][] dirs = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
    13. static List<Integer> ans = new ArrayList<>();
    14. static boolean is_end = false;
    15. static boolean judge(){
    16. for(int i = 0; i < n; i++){
    17. if(west1[i] != west2[i]){
    18. return false;
    19. }
    20. if(north1[i] != north2[i]){
    21. return false;
    22. }
    23. }
    24. return true;
    25. }
    26. static void dfs(int row, int col){
    27. if(row == n-1 && col == n-1){
    28. if(judge()){
    29. for(int i = 0; i < ans.size(); i++){
    30. if(i != ans.size()-1)
    31. System.out.printf(ans.get(i) + " ");
    32. else
    33. System.out.printf(ans.get(i) + "\n");
    34. }
    35. is_end = true;
    36. }
    37. return;
    38. }
    39. if(is_end){
    40. return;
    41. }
    42. if(west2[row] > west1[row] || north2[col] > north1[col]){
    43. return;
    44. }
    45. //向四个方向进行搜索
    46. for(int i = 0; i < 4; i++){
    47. int newRow = row + dirs[i][0];
    48. int newCol = col + dirs[i][1];
    49. if(newRow < 0 || newRow >= n || newCol < 0 || newCol >= n){
    50. continue;
    51. }
    52. if(!visited[newRow][newCol]){
    53. visited[newRow][newCol] = true;
    54. ans.add(map[newRow][newCol]);
    55. north2[newCol]++;
    56. west2[newRow]++;
    57. dfs(newRow, newCol);
    58. visited[newRow][newCol] = false;
    59. ans.remove(Integer.valueOf(map[newRow][newCol]));
    60. north2[newCol]--;
    61. west2[newRow]--;
    62. }
    63. }
    64. }
    65. public static void main(String[] args) {
    66. Scanner scan = new Scanner(System.in);
    67. n = scan.nextInt();
    68. north1 = new int[n];
    69. west1 = new int[n];
    70. north2 = new int[n];
    71. west2 = new int[n];
    72. for(int i = 0; i < n; i++){
    73. north1[i] = scan.nextInt();
    74. }
    75. for (int i = 0; i < n; i++){
    76. west1[i] = scan.nextInt();
    77. }
    78. map = new int[n][n];
    79. visited = new boolean[n][n];
    80. int num = 0;
    81. for(int i = 0; i < n; i++){
    82. for(int j = 0; j < n; j++){
    83. map[i][j] = num++;
    84. }
    85. }
    86. //深搜前的初始化
    87. visited[0][0] = true;
    88. ans.add(0);
    89. west2[0]++;
    90. north2[0]++;
    91. dfs(0, 0);
    92. //0 4 5 1 2 3 7 11 10 9 13 14 15
    93. }
    94. }