问题描述
我需要输出从'P'到'G'的最短方向。我已经使用 BFS 来实现它。问题如下图:
输入:'N'维迷宫 '#' - 墙 'G' - 幽灵 'P' - 吃豆子
//Input Maze
8
########
# #
# # ## #
# # #G#
#P ###
#### # #
#G #G#
########
输出:N/S/W/E方向
EX) E E E S S W W W
我的代码总是超出时间限制。我无法准确指出问题出在哪里。我的代码如下:
我为方向和坐标创建了一个“点”类。
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Maze{
static char[][] map;
static boolean[][] visited;
static int[] dr = {1,-1,0};
static int[] dc = {0,1};
static String[] compass = {"S","N","W","E"};
static int cur_x,cur_y,cur_dist,N;
static String nswe = "";
static String curnswe = "";
static String oldDir,dir;
static int sx,sy;
static int shortestdist;
public static class Point{
int x;
int y;
int dist;
String ns;
String dir;
public Point(int x,int y,int dist,String oldDir,String dir){
this.x = x;
this.y = y;
this.dist = dist;
if("".equals(oldDir)) {
this.ns = dir;
}
else { this.ns = oldDir + " " + dir;
}
}
}
这是 BFS 方法():
public static void bfs(int x,String dir){
Queue<Point> q = new LinkedList<Point>();
q.offer(new Point(x,y,dist,oldDir,dir));
while(!q.isEmpty()){
Point cur = q.poll();
cur_x = cur.x;
cur_y = cur.y;
cur_dist = cur.dist;
curnswe = cur.ns;
nswe = curnswe;
if(map[cur_x][cur_y]=='G') {
return;
}
for(int dir1 = 0; dir1<4; dir1++){
int r = cur_x + dr[dir1];
int c = cur_y + dc[dir1];
String d = compass[dir1];
if(r >= 0 && c >= 0 && r < N && c < N){
if(map[r][c]!='#')
if(!visited[r][c]){
q.offer(new Point(r,c,cur_dist+1,curnswe,d));
visited[r][c] = true;
}
}
}
}
q.clear();
}
这是我输入迷宫、解决(BFS)和打印出方向的代码的主要部分。
public static void main(String[] args) throws IOException{
BufferedReader input = new BufferedReader(new InputStreamReader(system.in));
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(input.readLine());
N = Integer.parseInt(st.nextToken());
int dist = 1;
map = new char[N][N];
visited = new boolean[N][N];
for(int i=0;i<N;i++){
String line = input.readLine();
for (int j=0; j<N; j++) {
char t = line.charat(j);
if(t=='P') {sx=i; sy=j;}
map[i][j] = line.charat(j);
}
}
bfs(sx,sy,"","");
output.write(nswe + " ");
output.flush();
}
}
解决方法
我认为您的代码很好,但未能按照评估人员的要求表现良好。 这意味着您需要更改算法。您是否尝试过 DFS 等其他策略?
public static void main(String[] args) throws IOException {
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(input.readLine());
N = Integer.parseInt(st.nextToken());
int dist = 1;
map = new char[N][N];
visited = new boolean[N][N];
for (int i = 0; i < N; i++) {
String line = input.readLine();
for (int j = 0; j < N; j++) {
char t = line.charAt(j);
if (t == 'P') {
sx = i;
sy = j;
}
map[i][j] = line.charAt(j);
}
}
long time = System.nanoTime();
bfs(sx,sy,dist,"",""); // bfs run
time = System.nanoTime() - time;
output.write(nswe + " in:" + time + " with bfs\n");
nswe = "";
time = System.nanoTime();
dfs(sx,new boolean[N][N]); // dfs run
time = System.nanoTime() - time;
output.write(nswe + " in:" + time + " with dfs");
output.flush();
}
private static int shortest = Integer.MAX_VALUE;
public static void dfs(int x,int y,int dist,String dir,boolean[][] vstd) {
int cur_x = x;
int cur_y = y;
vstd = Arrays.copyOf(vstd,vstd.length);
for (int i = 0; i < vstd.length; i++) {
vstd[i] = Arrays.copyOf(vstd[i],vstd[i].length);
}
String curnswe = dir;
// System.out.println("\n"+dir);
if (map[cur_x][cur_y] == 'G') {
if (shortest >= dist) {
shortest = dist;
nswe = curnswe;
}
return;
}
dist++;
if (shortest <= dist)
return;
for (int dir1 = 0; dir1 < 4; dir1++) {
int r = cur_x + dr[dir1];
int c = cur_y + dc[dir1];
String d = compass[dir1];
if (r >= 0 && c >= 0 && r < N && c < N) {
if (map[r][c] == ' ' || map[r][c] == 'G')
if (!vstd[r][c]) {
vstd[r][c] = true;
dfs(r,c,dir + compass[dir1] + " ",vstd);
}
}
}
}
输出:
8
########
# #
# # ## #
# # #G#
#P ###
#### # #
#G #G#
########
E E E S S W W W in:978000 with bfs
E E E S S W W W in:188100 with dfs
对于这个输入,dfs 在很短的时间内完成。尝试更大的例子。
注意:对于大量输入,它可能会导致 StackOverflowError。