2016 第七届 蓝桥杯 国赛 路径之谜

路径之谜

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

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

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

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

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

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

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

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

package lq.lq2016;

import java.util.Scanner;

/*
 * 
 * 
 */
/*20 20
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1  20
20 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1  

4 4
1 1 1 4
4 1 1 1
*/
public class RoadMistery {
    static int N, tot;
    static int maxn = 25;
    static int[] top = new int[maxn];
    static int[] left = new int[maxn];
    static int[] top2 = new int[maxn];
    static int[] left2 = new int[maxn];
    static int[] dx = { -1, 1, 0, 0 };
    static int[] dy = { 0, 0, -1, 1 };
    static int[] ans = new int[400];
    static int vis[][] = new int[25][25];

    static void dfs(int x, int y, int ind) {// 当前位于(x,y)点,搜索第ind个点


        if (ind == tot - 1 && x == N - 1 && y == N - 1) {
            boolean flag = true;

            for (int i = 0; i < N; i++)
                if (top2[i] != top[i]) {
                    return;

                }
            for (int i = 0; i < N; i++)
                if (left2[i] != left[i]) {
                    return;
                }
            System.out.print(0 + " ");
            for (int i = 0; i < tot - 1; i++) {

                System.out.print(ans[i] + " ");
            }

            return;
        }

        for (int i = 0; i < 4; i++) {

            int tx = x + dx[i], ty = y + dy[i];
            if (tx >= 0 && tx < N && ty >= 0 && ty < N && vis[tx][ty] == 0) {

                top2[ty]++;
                left2[tx]++;
                if (top2[ty] > top[ty] || left2[tx] > left[tx]) {// 两个条件不可分开continue,会造成
                    // vis[tx][ty]=0;
                    top2[ty]--;
                    left2[tx]--;
                    continue;
                }
                vis[tx][ty] = 1;
                ans[ind] = tx * N + ty;

                dfs(tx, ty, ind + 1);
                vis[tx][ty] = 0;
                // ans[ind]=tx*N+ty;
                top2[ty]--;
                left2[tx]--;
            }
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        N = sc.nextInt();
        for (int i = 0; i < N; i++) {
            top[i] = sc.nextInt();
            tot += top[i];
        }

        for (int i = 0; i < N; i++)
            left[i] = sc.nextInt();

        top2[0] = 1;
        left2[0] = 1;
        vis[0][0] = 1;
        dfs(0, 0, 0);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值