zoukankan      html  css  js  c++  java
  • Eleven puzzle_hdu_3095(双向广搜).java

    Eleven puzzle

    Time Limit: 20000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 463    Accepted Submission(s): 111

    Problem Description
    Partychen invents a new game named “Eleven Puzzle” .Just like the classic game “Eight Puzzle”,but there some difference between them:The shape of the board is different and there are two empty tiles.

    The tile in black means it’s empty 

    Each step you can move only one tile.
    Here comes the problem.How many steps at least it required to done the game.
     
    Input
    The first line of input contains one integer specifying the number of test cases to follow.
    Every case contains five lines to describe the initial status of the board. 0 means empty.

    It’s confirmed that the board is legal.
     
    Output
    Output one line for each testcase.Contain an integer denotes the minimum step(s) it need to complete the game.Or “No solution!” if it’s impossible to complete the game within 20 steps.
     
    Sample Input
    3 2 1 0 3 4 5 6 7 8 9 0 11 10 0 1 2 3 4 5 6 7 8 9 10 11 0 0 11 10 9 8 7 6 5 4 3 2 1 0
     
    Sample Output
    2 0 No solution!
     
    //8953704	2013-08-15 15:45:09	Accepted	3095	2562MS	27052K	6524 B	Java	zhangyi
    import java.util.ArrayDeque;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Queue;
    import java.util.Scanner;
    
    public class Hdu3095 {
    	private static Map<String,Integer> smap = new HashMap<String,Integer>();   //存储从初始状态搜索所到达的状态
    	private static Map<String, Integer> emap = new HashMap<String, Integer>();//存储从目的状态搜索所到达的状态
    	private static Status sStatus = null; //初始状态
    	private static Status eStatus = null;//目的状态
    	private static int [][] dirs = new int[][]{{1,0},{-1,0},{0,-1},{0,1}}; //方向
    	private static Queue<Status> sq = new ArrayDeque<Status>();
    	private static Queue<Status> eq = new ArrayDeque<Status>();
    	private final static Integer maxLevel = 10;
    	public static void main(String[] args) {
    		Scanner in = new Scanner(System.in);
    		int cases = in.nextInt();
    		while(cases-->0){
    			inputData(in);
    			if(eStatus.getStatus().equals(sStatus.getStatus())){//如果初始状态等于目的状态,输出0
    				System.out.println(0);
    			}else{
    				emap.put(eStatus.getStatus(), 0);
    				smap.put(sStatus.getStatus(), 0);
    				int step = doublcBFS(sq,eq);
    				if(step == -1 || step > 20){
    					System.out.println("No solution!");
    				}else{
    					System.out.println(step);
    				}
    			}
    		}
    	}
    	/**
    	 * 输入数据
    	 * @param in
    	 */
    	private static void inputData(Scanner in){
    		initResourse();
    		int value = 0;
    		sStatus.map[1][3] = in.nextInt();
    		eStatus.map[1][3] = value++;
    		for(int i = 2; i <= 4; ++i){
    			sStatus.map[2][i] = in.nextInt();
    			eStatus.map[2][i] = value++;
    		}
    		for(int i = 1; i <= 5; ++i){
    			sStatus.map[3][i] = in.nextInt();
    			eStatus.map[3][i] = value++;
    		}
    		for(int i = 2; i <= 4; ++i){
    			sStatus.map[4][i] = in.nextInt();
    			eStatus.map[4][i] = value++;
    		}
    		sStatus.map[5][3] = in.nextInt();
    		eStatus.map[5][3] = 0;
    		smap.clear();
    		emap.clear();
    		sStatus.initPoint();
    		eStatus.initPoint();
    		sq.clear();
    		eq.clear();
    		sq.add(sStatus);
    		eq.add(eStatus);
    	}
    
    	/**
    	 * 初始化数据
    	 */
    	private static void initResourse(){
    		sStatus = new Status();
    		eStatus = new Status();
    		for(int i = 0;i < sStatus.map.length; ++i){
    			Arrays.fill(sStatus.map[i], -1);
    			Arrays.fill(eStatus.map[i], -1);
    		}
    	}
    
    	/**
    	 * 双向搜索函数
    	 * @param sq 初始状态搜索所需要的队列
    	 * @param eq 目的状态搜索所需要的队列
    	 * @return 初始状态到达目的状态所需要的最小步数,如果在maxLevel数值之内没有结果,则返回-1
    	 */
    	private static int doublcBFS(Queue<Status> sq, Queue<Status> eq){
    		int x, y;
    		while(!sq.isEmpty()||!eq.isEmpty()){
    			if(!sq.isEmpty()){ //初始状态搜索
    				Status s = sq.poll();
    				for(int i = 0; i < s.points.size(); ++i ){
    					Point p = s.points.get(i);
    					for(int j = 0; j < dirs.length; ++j){
    						x = p.x + dirs[j][0];
    						y = p.y + dirs[j][1];
    						if(s.map[x][y] == -1 || s.map[x][y] == 0){
    							continue;
    						}
    						int [][] ms = copyArray(s.map);
    
    						ms[p.x][p.y] = ms[x][y];
    						ms[x][y] = 0;
    
    						Status status = new Status();
    						status.map = ms;
    						status.points.add(new Point(x,y));
    						status.points.add(s.points.get((i+1)%2).copyPoint());
    						status.level = s.level + 1;
    						String ss = status.getStatus();
    						if(emap.containsKey(ss)){   //如果与目的状态搜索到的状态相遇,刚返回步数
    							return emap.get(ss) + status.level;
    						}
    						if(!smap.containsKey(ss) && s.level <= maxLevel){
    							smap.put(ss, status.level);
    							sq.add(status);
    						}
    					}
    				}
    			}
    			if(!eq.isEmpty()){ //目的状态搜索
    				Status s = eq.poll();
    				for(int i = 0; i < s.points.size(); ++i ){
    					Point p = s.points.get(i);
    					for(int j = 0; j < dirs.length; ++j){
    						x = p.x + dirs[j][0];
    						y = p.y + dirs[j][1];
    						if(s.map[x][y] == -1 || s.map[x][y] == 0){
    							continue;
    						}
    						int [][] ms = copyArray(s.map);
    						ms[p.x][p.y] = ms[x][y];
    						ms[x][y] = 0;
    
    						Status status = new Status();
    						status.map = ms;
    						status.points.add(new Point(x,y));
    						status.points.add(s.points.get((i+1)%2).copyPoint());
    						status.level = s.level + 1;
    						String ss = status.getStatus();
    						if(smap.containsKey(ss)){//如果与初始状态搜索到的状态相遇,刚返回步数
    							return smap.get(ss) + status.level;
    						}
    						if(!emap.containsKey(ss) && s.level <= maxLevel){
    							emap.put(ss, status.level);
    							eq.add(status);
    						}
    					}
    				}
    			}
    		}
    		return -1;
    	}
    
    
    	/**
    	 * 打印一个二维数组
    	 * @param map
    	 */
    	private static void show(int [][] map){
    		StringBuilder sb = new StringBuilder();
    		for(int i = 1; i < map.length - 1; ++i){
    			for(int j = 1; j < map[i].length - 1; ++j){
    				if(map[i][j] == -1){
    					sb.append(' ');
    				}else{
    					sb.append(map[i][j]);
    				}
    			}
    			sb.append('
    ');
    		}
    		System.out.println(sb.toString());
    	}
    
    	/**
    	 * 拷贝一个二维数组
    	 * @param map
    	 * @return
    	 */
    	private static int[][] copyArray(int [][] map){
    		int [][] m = new int[map.length][map[0].length];
    		for(int i = 0; i < map.length; ++i){
    			System.arraycopy(map[i],0,m[i],0,map[i].length);
    		}
    		return m;
    	}
    }
    
    /**
     * 存储状态
     * @author Administrator
     *
     */
    class Status{
    	final static int N = 7;
    	int [][] map; //当前地图
    	List<Point> points; //当前0点坐标
    	int level = 0; //到达当前状态所需步数
    	public Status(){
    		map = new int[N][N];
    		points = new ArrayList<Point>();
    		level = 0;
    	}
    	public Status(int [][] map, List<Point> points, int level){
    		this.map = map;
    		this.points = points;
    		this.level = level;
    	}
    	public void initPoint(){
    		for(int i = 1; i < map.length -1; ++i){
    			for(int j = 1; j < map[i].length - 1; ++j){
    				if(map[i][j] == 0){
    					points.add(new Point(i,j));
    				}
    			}
    		}
    	}
    
    	/**
    	 * 返回一个可唯一标识当前状态的字符串
    	 * @return
    	 */
    	public  String getStatus(){
    		StringBuilder sb = new StringBuilder();
    		for(int i = 1; i < map.length -1; ++i){
    			for(int j = 1; j < map[i].length -1; ++j){
    				if(map[i][j] != -1){
    					sb.append(map[i][j]);
    					sb.append(',');
    				}
    			}
    		}
    		return sb.toString();
    	}
    }
    /**
     * 坐标
     * @author Administrator
     *
     */
    class Point{
    	int x;
    	int y;
    	public Point(){
    
    	}
    	public Point(int x, int y){
    		this.x = x;
    		this.y = y;
    	}
    	/**
    	 * 拷贝一个坐标
    	 * @return
    	 */
    	public Point copyPoint(){
    		Point p = new Point();
    		p.x = x;
    		p.y = y;
    		return p;
    	}
    }

    双向广搜


  • 相关阅读:
    [做题记录]数学#1
    [鸽鸽]
    有关VHDL中null, 在Verilog HDL 中的表示方法 YB
    有关Quartus如何自动生成 .pof 文件 YB
    javac、java命令如何编译运行目标类以及其类引入的外部jar包
    虚拟机装 CentOs 7 黑屏解决办法
    curl 访问https
    游戏命中判定:圆桌算法和程序实现
    Unity3d与dll文件
    C++异步网络库workflow及基于workflow实现的网络框架wfrest的安装使用心得
  • 原文地址:https://www.cnblogs.com/james1207/p/3260447.html
Copyright © 2011-2022 走看看