使用广度优先所搜,用distance[i][j]表示点(i,j)到最近出口的距离
对于题目给出的数据,一开始(2,1)(2,4)的distance为1{从(0,0)开始计算},其它点的distance都为一个比较大的值,且把这两个点加入“搜索点集合”中
不断的从“搜索点集合”中“拿出”一个点,当这个点的distance+1小于它旁边的另一个点的distance时,就跟新另一个点的distance,且把另一个点加入“搜索点集合”中。当然,这两个点必须是联通的。
直到集合为空,然后找出最大的distance
下面说明算法时间效率为O(w*h)
注意运行时间与向集合中加入点的次数成线性关系
考虑到只有一个出口时,每一个点的distance值仅会被更新一次,而有两个出口时每一个点的distance值最多被更新两次,所以每个点最多被加入集合两次,效率为O(w*h)
对于题目给出的数据,一开始(2,1)(2,4)的distance为1{从(0,0)开始计算},其它点的distance都为一个比较大的值,且把这两个点加入“搜索点集合”中
不断的从“搜索点集合”中“拿出”一个点,当这个点的distance+1小于它旁边的另一个点的distance时,就跟新另一个点的distance,且把另一个点加入“搜索点集合”中。当然,这两个点必须是联通的。
直到集合为空,然后找出最大的distance
下面说明算法时间效率为O(w*h)
注意运行时间与向集合中加入点的次数成线性关系
考虑到只有一个出口时,每一个点的distance值仅会被更新一次,而有两个出口时每一个点的distance值最多被更新两次,所以每个点最多被加入集合两次,效率为O(w*h)
Code
/**//*
ID: sdjllyh1
PROG: maze1
LANG: JAVA
complete date: 2008/12/21
complexity: O(w * h)
author: LiuYongHui From GuiZhou University Of China
more article: www.cnblogs.com/sdjls
*/
import java.io.*;
import java.util.*;
public class maze1
{
private static int w, h;
private static int[][] distance;//每个点离最近出口的距离
private static char[][] map;//迷宫地图
private static int longestDistance;//输出的答案
private static LinkedList points = new LinkedList();//广度优先搜索需要搜索的点队列
public static void main(String[] args) throws IOException
{
init();
run();
output();
System.exit(0);
}
private static void run()
{
//当还有需要搜索的点时
while (!points.isEmpty())
{
//获得当前需要搜索的点
point p = (point)points.getFirst();
//从队列中移除此点
points.removeFirst();
//分别考虑四个方向
for (int facing = 0; facing < 4; facing++)
{
//如果下一步可以走且此点的distance加1小于下一点的distance(发现最优路线)
if (canMoveAndBester(p, facing))
{
//获得下一点
point nextPoint = move(p, facing);
//跟新下一点的distance
distance[nextPoint.x][nextPoint.y] = distance[p.x][p.y] + 1;
//把下一点加入搜索队列
points.addLast(nextPoint);
}
}
}
//计算最大的distance
longestDistance = calcLongestDistance();
}
private static int calcLongestDistance()
{
int retDistance = 0;
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
retDistance = Math.max(retDistance, distance[i][j]);
}
}
return retDistance;
}
//如果下一点能走且从p点(当前点)走到下一点的方案更好时返回true
private static boolean canMoveAndBester(point p, int facing)
{
boolean retCanMove = true;
switch (facing)
{
case 0:
//如果走到边界或此方案不是更好的或有障碍物,下面类似
if ((p.x == 0) || (distance[p.x - 1][p.y] <= distance[p.x][p.y] + 1) || (map[p.x * 2][p.y * 2 + 1] == '-'))
{
retCanMove = false;
}
break;
case 1:
if ((p.y == w - 1) || (distance[p.x][p.y + 1] <= distance[p.x][p.y] + 1) || (map[p.x * 2 + 1][(p.y + 1) * 2] == '|'))
{
retCanMove = false;
}
break;
case 2:
if ((p.x == h - 1) || (distance[p.x + 1][p.y] <= distance[p.x][p.y] + 1) || (map[(p.x + 1) * 2][p.y * 2 + 1] == '-'))
{
retCanMove = false;
}
break;
case 3:
if ((p.y == 0) || (distance[p.x][p.y - 1] <= distance[p.x][p.y] + 1) || (map[p.x * 2 + 1][p.y * 2] == '|'))
{
retCanMove = false;
}
break;
}
return retCanMove;
}
//获得下一点,facing是方向,0、1、2、3分别表示上、右、下、左
private static point move(point p, int facing)
{
point retPoint = null;
switch (facing)
{
case 0:
retPoint = new point(p.x - 1, p.y);
break;
case 1:
retPoint = new point(p.x, p.y + 1);
break;
case 2:
retPoint = new point(p.x + 1, p.y);
break;
case 3:
retPoint = new point(p.x, p.y - 1);
break;
}
return retPoint;
}
private static void init() throws IOException
{
BufferedReader f = new BufferedReader(new FileReader("maze1.in"));
StringTokenizer st = new StringTokenizer(f.readLine());
w = Integer.parseInt(st.nextToken());
h = Integer.parseInt(st.nextToken());
map = new char[h*2+1][w * 2 + 1];
distance = new int[h][w];
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
distance[i][j] = Integer.MAX_VALUE;
}
}
for (int i = 0; i < h * 2 + 1; i++)
{
String str = f.readLine();
for (int j = 0; j < w * 2 + 1; j++)
{
map[i][j] = str.charAt(j);
if ((i == 0) && (map[i][j] == ' '))
{
distance[0][(j - 1) / 2] = 1;
points.addLast(new point(0, (j - 1) / 2));
}
if ((i == h * 2) && (map[i][j] == ' '))
{
distance[h - 1][(j - 1) / 2] = 1;
points.addLast(new point(h - 1, (j - 1) / 2));
}
if ((j == 0) && (map[i][j] == ' '))
{
distance[(i - 1) / 2][0] = 1;
points.addLast(new point((i - 1) / 2, 0));
}
if ((j == w * 2) && (map[i][j] == ' '))
{
distance[(i - 1) / 2][w - 1] = 1;
points.addLast(new point((i - 1) / 2, w - 1));
}
}
}
f.close();
}
private static void output() throws IOException
{
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("maze1.out")));
out.println(longestDistance);
out.close();
}
}
class point
{
public int x;
public int y;
public point(int x, int y)
{
this.x = x;
this.y = y;
}
}
/**//*
ID: sdjllyh1
PROG: maze1
LANG: JAVA
complete date: 2008/12/21
complexity: O(w * h)
author: LiuYongHui From GuiZhou University Of China
more article: www.cnblogs.com/sdjls
*/
import java.io.*;
import java.util.*;
public class maze1
{
private static int w, h;
private static int[][] distance;//每个点离最近出口的距离
private static char[][] map;//迷宫地图
private static int longestDistance;//输出的答案
private static LinkedList points = new LinkedList();//广度优先搜索需要搜索的点队列
public static void main(String[] args) throws IOException
{
init();
run();
output();
System.exit(0);
}
private static void run()
{
//当还有需要搜索的点时
while (!points.isEmpty())
{
//获得当前需要搜索的点
point p = (point)points.getFirst();
//从队列中移除此点
points.removeFirst();
//分别考虑四个方向
for (int facing = 0; facing < 4; facing++)
{
//如果下一步可以走且此点的distance加1小于下一点的distance(发现最优路线)
if (canMoveAndBester(p, facing))
{
//获得下一点
point nextPoint = move(p, facing);
//跟新下一点的distance
distance[nextPoint.x][nextPoint.y] = distance[p.x][p.y] + 1;
//把下一点加入搜索队列
points.addLast(nextPoint);
}
}
}
//计算最大的distance
longestDistance = calcLongestDistance();
}
private static int calcLongestDistance()
{
int retDistance = 0;
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
retDistance = Math.max(retDistance, distance[i][j]);
}
}
return retDistance;
}
//如果下一点能走且从p点(当前点)走到下一点的方案更好时返回true
private static boolean canMoveAndBester(point p, int facing)
{
boolean retCanMove = true;
switch (facing)
{
case 0:
//如果走到边界或此方案不是更好的或有障碍物,下面类似
if ((p.x == 0) || (distance[p.x - 1][p.y] <= distance[p.x][p.y] + 1) || (map[p.x * 2][p.y * 2 + 1] == '-'))
{
retCanMove = false;
}
break;
case 1:
if ((p.y == w - 1) || (distance[p.x][p.y + 1] <= distance[p.x][p.y] + 1) || (map[p.x * 2 + 1][(p.y + 1) * 2] == '|'))
{
retCanMove = false;
}
break;
case 2:
if ((p.x == h - 1) || (distance[p.x + 1][p.y] <= distance[p.x][p.y] + 1) || (map[(p.x + 1) * 2][p.y * 2 + 1] == '-'))
{
retCanMove = false;
}
break;
case 3:
if ((p.y == 0) || (distance[p.x][p.y - 1] <= distance[p.x][p.y] + 1) || (map[p.x * 2 + 1][p.y * 2] == '|'))
{
retCanMove = false;
}
break;
}
return retCanMove;
}
//获得下一点,facing是方向,0、1、2、3分别表示上、右、下、左
private static point move(point p, int facing)
{
point retPoint = null;
switch (facing)
{
case 0:
retPoint = new point(p.x - 1, p.y);
break;
case 1:
retPoint = new point(p.x, p.y + 1);
break;
case 2:
retPoint = new point(p.x + 1, p.y);
break;
case 3:
retPoint = new point(p.x, p.y - 1);
break;
}
return retPoint;
}
private static void init() throws IOException
{
BufferedReader f = new BufferedReader(new FileReader("maze1.in"));
StringTokenizer st = new StringTokenizer(f.readLine());
w = Integer.parseInt(st.nextToken());
h = Integer.parseInt(st.nextToken());
map = new char[h*2+1][w * 2 + 1];
distance = new int[h][w];
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
distance[i][j] = Integer.MAX_VALUE;
}
}
for (int i = 0; i < h * 2 + 1; i++)
{
String str = f.readLine();
for (int j = 0; j < w * 2 + 1; j++)
{
map[i][j] = str.charAt(j);
if ((i == 0) && (map[i][j] == ' '))
{
distance[0][(j - 1) / 2] = 1;
points.addLast(new point(0, (j - 1) / 2));
}
if ((i == h * 2) && (map[i][j] == ' '))
{
distance[h - 1][(j - 1) / 2] = 1;
points.addLast(new point(h - 1, (j - 1) / 2));
}
if ((j == 0) && (map[i][j] == ' '))
{
distance[(i - 1) / 2][0] = 1;
points.addLast(new point((i - 1) / 2, 0));
}
if ((j == w * 2) && (map[i][j] == ' '))
{
distance[(i - 1) / 2][w - 1] = 1;
points.addLast(new point((i - 1) / 2, w - 1));
}
}
}
f.close();
}
private static void output() throws IOException
{
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("maze1.out")));
out.println(longestDistance);
out.close();
}
}
class point
{
public int x;
public int y;
public point(int x, int y)
{
this.x = x;
this.y = y;
}
}