蓝桥杯89.路径之谜(java)
·


第一步:确定思路,通过题目观察,我们发现箭靶上箭的数量代表着所对应的行或者列,骑士所走的步数。然后把题目改成当成骑士从零开始想要走到最后,每个方向拥有相应的步数,所以可以得出结论,一直走到终点的时候,所有方向的步数为零的那一个方法就是题目要的路径。
第二步:设置变量,我们需要一个int类型的N存储地图格数,两个int类型的数组north[i]和west[i]分别用来存储对应列和行的步数,一个boolean类型的二维数组visit[i][j]表示第i行第j列的情况,一个boolean类型的found用来表示某一条路径是否是所需路径,一个List类型的path用来存放路径,然和按照dfs的模板,先写终止条件,再写每一步的消耗,最后写回溯就行了
代码如下:
import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
static int N;
static int[] north; // 北边靶
static int[] west; // 西边靶
static boolean[][] visited;
static List<Integer> path; // 记录路径的坐标序列
static boolean found; // 标记是否找到唯一路径
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
//对应靶子的数量相当于可以走的步数,可以遍历所有的路径,当某一条路径对应的步数全部为0而且走到了终点就说明是答案
//初始化
N = scan.nextInt();
north = new int[N];
west = new int[N];
for(int i=0;i<N;i++){
north[i] = scan.nextInt();
}
for(int i=0;i<N;i++){
west[i] = scan.nextInt();
}
visited = new boolean[N][N];
path = new ArrayList<>();
found = false;
//从起点开始
visited[0][0] = true;
west[0]--;
north[0]--;
path.add(0);
dfs(0,0);
for(int num:path){
System.out.print(num+" ");
}
scan.close();
}
public static void dfs(int x,int y){
//终止条件1
if(found){
return;
}
//终止条件2 到达终点且所有箭靶数为0
if(x==N-1&&y==N-1){
boolean allzero = true;
for(int num:north){
if(num!=0){
allzero=false;
break;//只要有一个不为零就可以跳出来了
}
}
for(int num:west){
if(num!=0){
allzero=false;
break;
}
}
if(allzero){
found = true;
}
return;
}
//操作
int[][] dirs = {{0,1},{1,0},{-1,0},{0,-1}};//四个方向
for(int[] dir:dirs){
int newx = x+dir[0];
int newy = y+dir[1];
//检查合法性 边界内+没有访问+还有步数
if(newx<N && newy<N && newx>=0 && newy>=0 && !visited[newx][newy] && north[newy]>0 && west[newx]>0){
north[newy]--;
west[newx]--;
visited[newx][newy] = true;
path.add(N*newx + newy);//编号转换
dfs(newx,newy);
//回溯
if(!found){
path.remove(path.size()-1);//撤销上一步
north[newy]++;
west[newx]++;
visited[newx][newy] = false;
}
}
}
}
}
更多推荐


所有评论(0)