POJ3984(BFS+路径还原)

package adv;

import java.util.ArrayDeque;
import java.util.Scanner;

/**
 * Poj3984迷宫问题
 * BFS+路径还原
 * 一般用于走迷宫/求最短路径,
 */
public class POJ3984 {
	static int T,n,m,ans;
	static int startx,starty,endx,endy;
	static int[][] map;
	static boolean[][] flag;
	static int[][] dir = {
   
   {0,-1},{0,1},{-1,0},{1,0}};//标记四个方向
	
	static Node[][] path;//标记路径
	static ArrayDeque<Node> list = new ArrayDeque<Node>();//添加路径
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		T = sc.nextInt();
		for(int test_case=1;test_case<=T;test_case++) {
			n = sc.nextInt();
			m = sc.nextInt();
			startx = sc.nextInt();
			starty = sc.nextInt();
			endx = sc.nextInt();
			endy = sc.nextInt();
			
			map = new int[n][m];
			flag = new boolean[n][m];//默认标识全部为false
			path = new Node[n][m];
			for(int i=0;i<n;i++) {
				for(int j=0;j<m;j++) {
					map[i][j] = sc.nextInt();
				}
			}
			bfs(new Node(startx, starty, 0),new Node(endx, endy, 0));
			System.out.println("#"+test_case+" "+ans);
			for (Node node : list) {
				System.out.println("{"+node.x+","+node.y+"}");
			}
		}
		
	}
	/**
	 * 从起点到终点bfs搜索
	 * @param start 起点
	 * @param end	终点
	 */
	public static void bfs(Node start,Node end) {
		ArrayDeque<Node> que = new ArrayDeque<Node>();
		que.add(start);
		
		while(!que.isEmpty()) {
			Node node = que.getFirst();
			que.removeFirst();
			//四个相邻的位置
			for(int i=0;i<4;i++) {
				Node dirNode = new Node(node.x+dir[i][0], node.y+dir[i][1],node.time+1);
				//相邻位置有效,且未被标记
				if(isVal(dirNode)) {
					path[dirNode.x][dirNode.y] = node; 
					if(dirNode.equals(end)) {
						list.add(end);
						list.addFirst(path[dirNode.x][dirNode.y]);
						int beforX = path[dirNode.x][dirNode.y].x;
						int beforY = path[dirNode.x][dirNode.y].y;
						
						while(!(beforX==start.x && beforY==start.y)) {
							list.addFirst(path[beforX][beforY]);
							int xx = path[beforX][beforY].x;
							int yy = path[beforX][beforY].y;
							beforX = xx;
							beforY = yy;
						}
						ans = dirNode.time;
						return ;
					}
					que.addLast(dirNode);
					flag[dirNode.x][dirNode.y] = true;
				}
			}
		}
	}
	/**
	 * 判断一个坐标是否有效
	 * @param node
	 * @return true有效 ,false无效
	 */
	public static boolean isVal(Node node) {
		int x = node.x;
		int y = node.y;
		return x>=0 && x<n && y>=0 && y<m && flag[x][y]==false && map[x][y]!=1?true:false;
	}
	
}
/**
 * 坐标对象
 * @author XA-GDD
 *
 */
class Node{
	int x,y,time;
	public Node(int x,int y,int time) {
		this.x = x;
		this.y = y;
		this.time = time;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + x;
		result = prime * result + y;
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Node other = (Node) obj;
		if (x != other.x)
			return false;
		if (y != other.y)
			return false;
		return true;
	}
	
}

广度/宽度优先搜索(BFS)

猜你喜欢

转载自blog.csdn.net/qq_28635317/article/details/111473480