您的位置:首页 > 其它

华为机试 迷宫最短路径

2016-09-10 00:24 218 查看
闯迷宫
描述:sun所在学校每年都要举行电脑节,今年电脑节有一个新的趣味比赛项目叫做闯迷宫。
sun的室友在帮电脑节设计迷宫,所以室友就请sun帮忙计算下走出迷宫的最少步数。
知道了最少步数就可以辅助控制比赛难度以及去掉一些没有路径到达终点的map。
比赛规则是:从原点(0,0)开始走到终点(n-1,n-1),只能上下左右4个方向走,只能在给定的矩阵里走。
运行时间限制:10 Sec
内存限制:128 MByte
输入:输入有多组数据。


每组数据输入n(0<n<=100),然后输入n*n的0、1矩阵,0代表该格子没有障碍,为1表示有障碍物。
注意:如果输入中的原点和终点为1则这个迷宫是不可达的。
输出:对每组输入输出该迷宫的最短步数,若不能到达则输出-1。

样例输入:
2
0 1
0 0
5
0 0 0 0 0
1 0 1 0 1
0 0 0 0 0
0 1 1 1 0
1 0 1 0 0

样例输出:
2
8

BFS实现版:

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

class Point{

int x,y;
public Point(int x,int y) {
// TODO Auto-generated constructor stub
this.x=x;
this.y=y;

}

}
public class Main {

static final int unreachable=100000;     //代表从未走过
static int dx[]={0,1,0,-1};
static int dy[]={1,0,-1,0};
public static void main(String[] args) {
// TODO Auto-generated method stub

Scanner in=new Scanner(System.in);
while (in.hasNextInt()) {

int n=in.nextInt();
int m=n;
int maze[][]=new int

;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
maze[i][j]=in.nextInt();
}
}

if (maze[0][0]==1||maze[n-1][n-1]==1) {
System.out.println(-1);
continue;
}

int distance[][]=new int

;
initDistance(distance);
distance[0][0]=0;
int dis=bfs(maze,distance,n);
if (dis==unreachable) {
System.out.println(-1);
}else {
System.out.println(dis);
}

}
}
private static int bfs(int[][] maze, int[][] distance, int n) {
// TODO Auto-generated method stub

Queue<Point> q=new LinkedList<Point>();
q.offer(new Point(0, 0));

while (!q.isEmpty()) {
Point front=q.poll();
if (front.x==n-1&&front.y==n-1) {
break;
}

for (int i = 0; i < 4; i++) {     //上下左右
int px=front.x+dx[i];
int py=front.y+dy[i];

if (px>=0&&px<n&&py>=0&&py<n&&maze[px][py]!=1&&distance[px][py]==unreachable) {
q.add(new Point(px, py));
distance[px][py]=distance[front.x][front.y]+1;
}
}
}
return distance[n-1][n-1];
}
private static void initDistance(int[][] distance) {
// TODO Auto-generated method stub
for (int i = 0; i < distance.length; i++) {
for (int j = 0; j < distance.length; j++) {
distance[i][j]=unreachable;
}
}

}

}


测试结果:



下面再给出DFS版本的解法

import java.util.Scanner;
import java.util.Stack;

class point{

int x,y;
public point(int x,int y) {
// TODO Auto-generated constructor stub
this.x=x;
this.y=y;
}

}
public class DFSMaze {
static final int unreachable=100000;
static int dx[]={0,1,0,-1};
static int dy[]={1,0,-1,0};
static int steps=-1;
public static void main(String[] args) {
// TODO Auto-generated method stub

Scanner in=new Scanner(System.in);
while (in.hasNextInt()) {

int n=in.nextInt();
int m=n;
int maze[][]=new int

;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
maze[i][j]=in.nextInt();
}
}

if (maze[0][0]==1||maze[n-1][n-1]==1) {
System.out.println(-1);
continue;
}
boolean visit[][]=new boolean

;

Stack<point> stack=new Stack<point>();
int dis=dfs (maze,n,stack,visit);

System.out.println(dis);

}
}
private static int dfs(int[][] maze, int n, Stack<point> stack, boolean[][] visit) {
// TODO Auto-generated method stub

recursive(maze,n,stack,0,0,visit);
return steps;
}
private static void recursive(int[][] maze, int n, Stack<point> stack, int x, int y, boolean[][] visit) {
// TODO Auto-generated method stub
stack.push(new point(x, y));
if (x==n-1&&y==n-1) {
System.out.println("Start.......");
for (point p : stack) {
System.out.println("("+p.x+","+p.y+")");
}
System.out.println("End........");
steps=stack.size()-1;
return;
}
visit[x][y]=true;
for (int i = 0; i <4; i++) {
int px=x+dx[i];
int py=y+dy[i];
if (px>=0&&px<n&&py>=0&&py<n&&maze[px][py]!=1&&visit[px][py]==false) {
recursive(maze, n, stack, px, py,visit);
}
}
stack.pop();
visit[x][y]=false;

}

}


测试结果:



//以下通用版,S代表起始点,G代表出口

实现代码:

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
* Created by yangjianzhou on 2014/8/18 21:36.
* TODO :给定一个大小为N*M的迷宫,迷宫由通道和墙壁组成,每一步可以向邻接的上下左右四
* 格的通道移动。求从起点到终点所需的最小步数。
*/
public class Maze {

private static final int INF = 100000;  // 表示没有走过
private static final int N = 10;
private static final int M = 10;
private static char[][] mazeMatrix = {
{'#', 'S', '#', '#', '#', '#', '#', '#', 'o', '#'},
{'o', 'o', 'o', 'o', 'o', 'o', '#', 'o', 'o', '#'},
{'o', '#', 'o', '#', '#', 'o', '#', '#', 'o', '#'},
{'o', '#', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
{'#', '#', 'o', '#', '#', 'o', '#', '#', '#', '#'},
{'o', 'o', 'o', 'o', '#', 'o', 'o', 'o', 'o', '#'},
{'#', '#', '#', '#', '#', '#', '#', '#', 'o', '#'},
{'o', 'o', 'o', '#', 'o', 'o', 'o', 'o', 'o', 'o'},
{'o', '#', '#', '#', '#', 'o', '#', '#', '#', 'o'},
{'o', 'o', 'o', 'o', '#', 'o', 'o', 'o', 'G', '#'}
};
;
private static int xs = 0;
private static int ys = 1;
private static int xe = 9;
private static int ye = 8;
private static int[][] distance = new int
[M];

private static int[] xd = {1, 0, -1, 0};
private static int[] yd = {0, 1, 0, -1};

public static void main(String[] args) {
initDistance();
Maze maze = new Maze();
int dis = maze.bfs();
System.out.println("shortest length is : " + dis);
printDistance();
}

private int bfs() {
Queue<Point> que = new ConcurrentLinkedQueue<Point>();
que.add(new Point(xs, ys));
distance[xs][ys] = 0;
while (que.size() > 0) {
Point point = que.poll();
if (point.getX() == xe && point.getY() == ye) {
break;
}
for (int i = 0; i < 4; i++) {
int xp = point.getX() + xd[i];
int yp = point.getY() + yd[i];
if (0 <= xp && xp < N && 0 <= yp && yp < M && mazeMatrix[xp][yp] != '#' && distance[xp][yp] == INF) {
que.add(new Point(xp, yp));
distance[xp][yp] = distance[point.getX()][point.getY()] + 1;
}
}
}
return distance[xe][ye];
}

private static void initDistance() {
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
distance[i][j] = INF;
}
}
}

private static void printDistance() {
for (int i = 0; i < N; i++) {
System.out.println();
for (int j = 0; j < M; j++) {
System.out.print("\t\t" + distance[i][j]);
}
}
}

class Point {
int x;
int y;

public Point(int x, int y) {
this.x = x;
this.y = y;
}

public int getX() {
return x;
}

public int getY() {
return y;
}

public void setX(int x) {
this.x = x;
}

public void setY(int y) {
this.y = y;
}
}
}


测试结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: