uva816

思路:主要是方向判断

package test;

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


public class Test{	
	static Scanner sc = new Scanner(System.in);
	static String line;
	
	public static class Node{
		int r,c,dir;
		
		public Node(int r, int c, int dir) {
			super();
			this.r = r;
			this.c = c;
			this.dir = dir;
		}				
		
		@Override
		public boolean equals(Object obj) {
			Node n = (Node) obj;
			return (r==n.r&&c==n.c);		
		}			
		
		@Override
		public String toString() {			
			return "("+r+","+c+")";
		}
	}
	
	static char[] dirs = {'N','E','S','W'};
	static char[] turns = {'F','L','R'};
	
	static int[] dr = {-1,0,1,0};//与dc构成是个方向上的坐标变动
	static int[] dc = {-1,0,1,0};
	
	static int n = 9;//迷宫行列数
	static int[][][][] has_edge = new int[n][n][4][3];//记录某点,四个方向进入,某个方向对应的三种转向是否存在
	static int[][][] d = new int[n][n][4];//表示从初状态到r,c,dir的最短路径的长度
	
	static Node[][][] p = new Node[n][n][4];//记录父路径
	
	static int r1,c1,dir;//初始状态
	static int r2,c2;//目标状态
	/**
	 * 把方向字符转换成数字
	 * @param c
	 * @return
	 */
	static int dir_id(char c){
		return Arrays.binarySearch(dirs, c);		 
	}
	
	/**
	 * 把转向字符转换成数字
	 * @param c
	 * @return
	 */
	static int turn_id(char c){
		return Arrays.binarySearch(turns, c);		 
	}
	
	/**
	 * 改变转向
	 * @param u
	 * @param turn
	 * @return
	 */
	static Node walk(Node u, int turn){
		int dir = u.dir;
		if(turn == 1) dir = (dir+3)%4;//逆时针
		if(turn == 2) dir = (dir+1)%4;//顺时针
		return new Node(u.r,u.c,dir);
	}
	
	static void solve(){			
		Queue<Node> queue = new LinkedList <Node>();//栈
		Node n = new Node(r1,c1,dir);//起始点		
		queue.add(n);
		
		while(!queue.isEmpty()){
			Node u = queue.poll();
			if(u.r==r2&&u.c==r2){
				print_ans(u);
				return;
			}
			for(int i=0;i<3;i++){
				Node v = walk(u,i);//转身
				if(has_edge[v.r][v.c][v.dir][i]==1 && d[v.r][v.c][v.dir]<1 
						&& inside(v.r,v.c)){//如果存在该方向,并且没有走过,并且
					d[v.r][v.c][v.dir] = d[u.r][u.c][u.dir] + 1;//路径加一
					p[v.r][v.c][v.dir] = u;//记录下父节点
					queue.add(v);
				}
			}
		}	
	}
	
	static boolean inside(int x,int y){
	  if(x>=1&&x<=n&&y>=1&&y<=n) return true;
	  return false;
	}
	
	private static void print_ans(Node u) {
		ArrayList<Node> nodes = new ArrayList<Node>();
		for(;;){
			nodes.add(u);
			if(d[u.r][u.c][u.dir]==0) break;
			u = p[u.r][u.c][u.dir];
		}
		
		System.out.println(nodes);
	}

	public static void main(String[] args) {
		solve();
		System.out.println(Arrays.deepToString(p));
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值