题目描述


小明冒充X星球的骑士,进入了一个奇怪的城堡。
城堡里边什么都没有,只有方形石头铺成的地面。

假设城堡地面是 n x n 个方格。【如图1.png】所示。

按习俗,骑士要从西北角走到东南角。
可以横向或纵向移动,但不能斜着走,也不能跳跃。
每走到一个新方格,就要向正北方和正西方各射一箭。
(城堡的西墙和北墙内各有 n 个靶子)

同一个方格只允许经过一次。但不必做完所有的方格。

如果只给出靶子上箭的数目,你能推断出骑士的行走路线吗?

有时是可以的,比如图1.png中的例子。

本题的要求就是已知箭靶数字,求骑士的行走路径(测试数据保证路径唯一)

输入:
第一行一个整数N(0

解题思路


/* 本题初次一看,还是比较令人愉快的,并不是很难。 如果读者迷宫问题很熟练,这道题坑定也没问题。 就是对迷宫加了一点要求而已。详细叙述见代码。 */

代码


import java.util.Scanner;
public class Main{
    static int[] row ;//保存自西向东靶子上的数目
    static int[] col; //保存自北向南靶子的数目
    static int[][] vis ; // 标记数组,标记迷宫的方格是否走过
    static int N; 
    //上下左右四个方向
    static int[][] point = {{0,1},{1,0},{0,-1},{-1,0}};
    //转换成0--N^2-1的数组,输出要求 
    static int[][] print;
    static int rowSum = 0;//北边靶子的总数目
    static int colSum = 0;//西边靶子的总数目
    static int[] map = null; //满足要求的行走路径
    static int k =1; //可行路径的长度
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        N = sc.nextInt();
        //init
        row = new int[N];
        col = new int[N];
        vis = new int[N][N];
        print = new int[N][N];
        map = new int[N*N+1];
        int index = 0;
        for(int i=0; i<N; ++i)
            for(int j=0; j<N; ++j)
                print[i][j] = index++;
        //input
        for(int i=0; i<N; ++i){
            row[i] = sc.nextInt();
            rowSum += row[i];
        }
        for(int i=0; i<N; ++i){
            col[i] = sc.nextInt();
            colSum += col[i];
        }
        //process
        row[0]--;
        rowSum--;
        col[0]--;
        colSum--;
        vis[0][0] = 1;
        map[0] = 0;
        //从0,0出发
        dfs(0,0);
    }

    public static void dfs(int x, int y){
        if(x==N-1 && y==N-1){
            //print
            if(rowSum==0 && colSum==0){
                for(int i=0; i<k; ++i)
                    System.out.print(map[i]+" ");
            }
        }
        for(int i=0; i<4; ++i){
            int dx = x + point[i][0];
            int dy = y + point[i][1];
            //约束条件:1.没出界,2.行列上的靶子数目至少为1
            if (dx >= 0 && dx < N && dy >= 0 && dy < N && vis[dx][dy] == 0 && row[dy] > 0 && col[dx] > 0) {
                vis[dx][dy] = 1;
                row[dy]--;
                rowSum--;
                col[dx]--;
                colSum--;
                map[k++] = print[dx][dy];
                dfs(dx, dy);
                k--; //走不通,直接将map数组的k--
                vis[dx][dy] = 0;
                row[dy]++;
                rowSum++;
                col[dx]++;
                colSum++;
            }
        }
    }
}