第一步:确定思路,通过题目观察,我们发现箭靶上箭的数量代表着所对应的行或者列,骑士所走的步数。然后把题目改成当成骑士从零开始想要走到最后,每个方向拥有相应的步数,所以可以得出结论,一直走到终点的时候,所有方向的步数为零的那一个方法就是题目要的路径。

第二步:设置变量,我们需要一个int类型的N存储地图格数,两个int类型的数组north[i]和west[i]分别用来存储对应列和行的步数,一个boolean类型的二维数组visit[i][j]表示第i行第j列的情况,一个boolean类型的found用来表示某一条路径是否是所需路径,一个List类型的path用来存放路径,然和按照dfs的模板,先写终止条件,再写每一步的消耗,最后写回溯就行了

代码如下:

import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    static int N;
    static int[] north;  // 北边靶
    static int[] west;   // 西边靶
    static boolean[][] visited;
    static List<Integer> path;  // 记录路径的坐标序列
    static boolean found;     // 标记是否找到唯一路径
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        //在此输入您的代码...
        //对应靶子的数量相当于可以走的步数,可以遍历所有的路径,当某一条路径对应的步数全部为0而且走到了终点就说明是答案
        //初始化
        N = scan.nextInt();
        north = new int[N];
        west = new int[N];
        for(int i=0;i<N;i++){
          north[i] = scan.nextInt();
        }
        for(int i=0;i<N;i++){
          west[i] = scan.nextInt();
        }
        visited = new boolean[N][N];
        path = new ArrayList<>();
        found = false;
        //从起点开始
        visited[0][0] = true;
        west[0]--;
        north[0]--;
        path.add(0);
        dfs(0,0);
        for(int num:path){
          System.out.print(num+" ");
        }
        scan.close();
    }
    public static void dfs(int x,int y){
      //终止条件1
      if(found){
        return;
      }
      //终止条件2 到达终点且所有箭靶数为0
      if(x==N-1&&y==N-1){
        boolean allzero = true;
        for(int num:north){
          if(num!=0){
            allzero=false;
            break;//只要有一个不为零就可以跳出来了
          }
        }
        for(int num:west){
          if(num!=0){
            allzero=false;
            break;
          }
        }
        if(allzero){
          found = true;
        }
        return;
      }
      //操作
      int[][] dirs = {{0,1},{1,0},{-1,0},{0,-1}};//四个方向
      for(int[] dir:dirs){
        int newx = x+dir[0];
        int newy = y+dir[1];
        //检查合法性 边界内+没有访问+还有步数
        if(newx<N && newy<N && newx>=0 && newy>=0 && !visited[newx][newy] && north[newy]>0 && west[newx]>0){
          north[newy]--;
          west[newx]--;
          visited[newx][newy] = true;
          path.add(N*newx + newy);//编号转换
          dfs(newx,newy);
          //回溯
          if(!found){
            path.remove(path.size()-1);//撤销上一步
            north[newy]++;
            west[newx]++;
            visited[newx][newy] = false;
          }
        }
      }
    }
}

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐