路径之谜——DFS

该问题描述了一个骑士在N×N的网格中,从西北角到东南角的行走路径,每走过一个方格会向北和西各射一箭到靶子上。给定靶子上的箭数,需要找出骑士的行走路径。通过深度优先搜索(DFS)算法,可以从起点开始递归探索所有可能的路径,当找到唯一满足条件的路径时停止搜索并输出路径。代码示例展示了如何实现这一过程。
摘要由CSDN通过智能技术生成

小明冒充 X 星球的骑士,进入了一个奇怪的城堡。

城堡里边什么都没有,只有方形石头铺成的地面。

假设城堡地面是 n×n 个方格。如下图所示。

按习俗,骑士要从西北角走到东南角。可以横向或纵向移动,但不能斜着走,也不能跳跃。每走到一个新方格,就要向正北方和正西方各射一箭。(城堡的西墙和北墙内各有 n 个靶子)同一个方格只允许经过一次。但不必走完所有的方格。如果只给出靶子上箭的数目,你能推断出骑士的行走路线吗?有时是可以的,比如上图中的例子。

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

输入描述

第一行一个整数 N (0≤N≤20),表示地面有 N×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 Main {
	static int n;
	static int[][] arr;
	static int[] row;
	static int[] col;
	static int[] dx = {0,1,0,-1};
	static int[] dy = {1,0,-1,0};
	static int[] path;
	static int[][] visit;
	static boolean success;
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scan = new Scanner(System.in);
		n = scan.nextInt();
		arr = new int[n][n];
		row = new int[n];
		col = new int[n];
		visit = new int[n][n];
		path = new int[n * n];
		for(int i = 0; i < n; i++) {
			row[i] = scan.nextInt();
		}
		for(int i = 0; i < n; i++) {
			col[i] = scan.nextInt();
		}
		dfs(0,0,0);
		
	}
	
	public static void dfs(int x, int y, int step) {
		path[step] = y * n + x;
		visit[x][y] = 1;
		row[x]--;
		col[y]--;
		if(x == n-1 && y == n-1 && check()) {
//			success = true;
			for(int i = 0; i <= step; i++) {
				System.out.print(path[i]+" ");
			}
			return;
		}
		for(int i = 0; i < 4; i++) {
			int nx = x+dx[i];
			int ny = y+dy[i];
//			!success &&
			if(nx >= 0 && nx < n && ny >=0 && ny < n && visit[nx][ny] == 0) { 
				if( row[nx] > 0 && col[ny] > 0) {
				    dfs(nx,ny,step+1);
				    visit[nx][ny] = 0;
				    row[nx]++;
				    col[ny]++;
				}
				
			}
		}
	}
	
	public static boolean check() {
		for (int i = 0; i < n; ++i) {
		      if (row[i] != 0 || col[i] != 0)
		        return false;
		    }
		    return true;
	}

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值