蓝桥杯决赛--路径之谜
题目描述
小明冒充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++;
}
}
}
}