• java实现第七届蓝桥杯路径之谜


    路径之谜

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

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

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

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

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

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

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

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

    输出:
    一行若干个整数,表示骑士路径。

    为了方便表示,我们约定每个小格子用一个数字代表,从西北角开始编号: 0,1,2,3…
    比如,图1.png中的方块编号为:

    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

    资源约定:
    峰值内存消耗 < 256M
    CPU消耗 < 1000ms

    请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

    所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
    注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
    注意:主类的名字必须是:Main,否则按无效代码处理。

    在这里插入图片描述

    // 常规的深搜+剪枝
    import java.util.ArrayList;
    import java.util.Scanner;
     
    public class Main {
    	// 下一步的方向
    	static int[][] dir = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };
    	// 结果
    	static ArrayList<Integer> list = new ArrayList<Integer>();
     
    	static int N;
    	// 记录北边的箭靶
    	static int[] north;
    	// 记录西边的箭靶
    	static int[] west;
    	// 记录走过的方格
    	static byte[] visit;
     
    	public static void main(String[] args) {
    		Scanner sc = new Scanner(System.in);
    		N = sc.nextInt();
    		north = new int[N];
    		west = new int[N];
     
    		for (int i = 0; i < N; i++) {
    			north[i] = sc.nextInt();
    		}
    		for (int i = 0; i < N; i++) {
    			west[i] = sc.nextInt();
    		}
     
    		// visit[i]为0,表示未被走过;visit[i]为1,表示已经走过。
    		visit = new byte[N * N];
     
    		dfs(0, 0);
     
    		sc.close();
    	}
     
    	static void dfs(int x, int y) {
    		int index = x * N + y;
    		visit[index] = 1;
    		north[y]--;
    		west[x]--;
    		list.add(index);
     
    		if (index == N * N - 1) {
    			for (int i = 0; i < N; i++) {
    				if (north[i] > 0 || west[i] > 0)
    					return;
    			}
    			for (int i = 0; i < list.size(); i++) {
    				System.out.print(list.get(i) + " ");
    			}
    			return;
    		}
     
    		for (int i = 0; i < dir.length; i++) {
    			int nextx = x + dir[i][0];
    			int nexty = y + dir[i][1];
    			if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= N)
    				continue;
    			if (north[nexty] <= 0 || west[nextx] <= 0)
    				continue;
    			dfs(nextx, nexty);
    			list.remove(list.size() - 1);
    			north[nexty]++;
    			west[nextx]++;
    			visit[nextx * N + y] = 0;
    		}
    	}
    }
    
    
  • 相关阅读:
    优化正则表达式的诀窍
    C#中的正则表达式
    正则表达式-- 零宽断言与懒惰匹配以及平衡组
    Match类
    RegexOptions枚举
    Regex类
    正则表达式-- 元字符
    正则表达式30分钟入门教程
    StreamReader与StreamWriter
    When do we pass arguments by reference or pointer?
  • 原文地址:https://www.cnblogs.com/a1439775520/p/13077254.html
Copyright © 2020-2023  润新知