[蓝桥杯2016决赛路径之谜] java+dfs+剪枝

题目描述

小明冒充X星球的骑士,进入了一个奇怪的城堡。城堡里边什么都没有,只有方形石头铺成的地面。
假设城堡地面是 n x n 个方格。
按习俗,骑士要从西北角走到东南角。可以横向或纵向移动,但不能斜着走,也不能跳跃。
每走到一个新方格,就要向正北方和正西方各射一箭。(城堡的西墙和北墙内各有 n 个靶子)
同一个方格只允许经过一次。但不必走完所有的方格。
如果只给出靶子上箭的数目,你能推断出骑士的行走路线吗?
有时是可以的,比如图中的例子。

本题的要求就是已知箭靶数字,求骑士的行走路径(测试数据保证路径唯一)
在这里插入图片描述

输入

第一行一个整数N(0<N<20),表示地面有 N x N 个方格
第二行N个整数,空格分开,表示北边的箭靶上的数字(自西向东)
第三行N个整数,空格分开,表示西边的箭靶上的数字(自北向南)

输出

一行若干个整数,表示骑士路径
为了方便表示,我们约定每个小格子用一个数字代表,从西北角开始编号: 0,1,2,3…
比如,上图中的方块编号为:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15

样例输入

4
2 4 3 4
4 3 3 3

样例输出

0 4 5 1 2 3 7 11 10 9 13 14 15

import java.util.*;
public class 蓝桥杯2016决赛路径之谜 {
    public static int mapp[][] = new int[100][100];
    public static int vis[][] = new int[100][100];
    public static int n;
    public static int A[] = new int[100];
    public static int B[] = new int[100];
    public static int num[][] = new int[100][2];
    public static int next[][] = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };
    public static int ANS2[] = new int[100];

    public static boolean check() { //检查函数
        for (int i = 0; i < n; i++) {
            if (num[i][0] > A[i] || num[i][1] > B[i])
                return false;
        }
        return true;
    }

    public static void dfs(int x, int y, int step, int k, int flag) {
        if (flag == 1)
            return;
        if (!check() || step > k) {
            return;
        }
        if (step == k) {
            if (x == n - 1 && y == n - 1) {
                if (check()) {
                    for (int i = 0; i < k; i++) {
                        System.out.print(ANS2[i] + " ");
                    }
                    flag = 1;
                    return;
                }
            }
        }
        for (int i = 0; i < 4; i++) {
            int xx = x + next[i][0];
            int yy = y + next[i][1];
            if (xx >= 0 && xx < n && yy >= 0 && yy < n) {
                if (vis[xx][yy] == 0) {
                    vis[xx][yy] = 1;
                    num[xx][1]++;
                    num[yy][0]++;
                    ANS2[step] = mapp[xx][yy];
                    dfs(xx, yy, step + 1, k, flag);
                    vis[xx][yy] = 0;
                    num[xx][1]--;
                    num[yy][0]--;
                    ANS2[step] = 0;
                }
            }
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        vis[0][0] = 1;
        num[0][0] = 1;
        num[0][1] = 1;
        n = sc.nextInt();
        int ans = 0;
        for (int i = 0; i < n; i++) {
            A[i] = sc.nextInt();
            ans += A[i];
        }
        for (int j = 0; j < n; j++) {
            B[j] = sc.nextInt();
            ans += B[j];
        }
        int jsq = 0; //计算器
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++) {
                mapp[i][j] = jsq;
                jsq++;
            }
        ans /= 2;
        dfs(0, 0, 1, ans, 0);
    }
}
 

发布了23 篇原创文章 · 获赞 0 · 访问量 368

猜你喜欢

转载自blog.csdn.net/qq_43328587/article/details/104396382