第四届蓝桥杯决赛题-九宫重排(双向广搜).java

问题描述
  如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。

  我们把第一个图的局面记为:12345678.
  把第二个图的局面记为:123.46758
  显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
  本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
输入格式
  输入第一行包含九宫的初态,第二行包含九宫的终态。
输出格式
  输出最少的步数,如果不存在方案,则输出-1。
样例输入
12345678.
123.46758
样例输出
3
样例输入
13524678.
46758123.
样例输出
22

/*
 * 132757	张燚	九宫重排	  2014-03-08 21:56	5.209KB	JAVA	正确	 100	156ms	33.90MB	评测详情  
 * 
 * 
 */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
public class Main{//双向广搜
	private static HashMap<String,Integer> hm1=null,hm2=null;
	public static void main(String[] args) {
		BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
		try {
			String start=bf.readLine();
			String end=bf.readLine();
			char a[][]=new char[3][3];
			char b[][]=new char[3][3];
			int c=0;
			int x1=0,y1=0,x2=0,y2=0;
			for(int i=0;i<3;i++){
				for(int j=0;j<3;j++){
					a[i][j]=start.charAt(c);
					b[i][j]=end.charAt(c);
					if(a[i][j]=='.'){
						x1=i;
						y1=j;
					}
					if(b[i][j]=='.'){
						x2=i;
						y2=j;
					}
					c++;
				}
			}
			Node node1=new Node(a,0,x1,y1);
			Node node2=new Node(b,0,x2,y2);
			Queue<Node> q1=new LinkedList<Node>();
			Queue<Node> q2=new LinkedList<Node>();
			hm1=new HashMap<String, Integer>();
			hm2=new HashMap<String, Integer>();
			hm1.put(start, 0);
			hm2.put(end, 0);
			q1.add(node1);
			q2.add(node2);
			System.out.println(bfs(q1,q2));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	private static int bfs(Queue<Node> q1,Queue<Node> q2) {
		while(!q1.isEmpty()||!q2.isEmpty()){
			if(!q1.isEmpty()){
				
				Node node1=q1.poll();
			//	System.out.println(node1.getTuString()+"----1");
				if(hm2.containsKey(node1.getTuString())){
					return node1.getSum()+hm2.get(node1.getTuString());
				}
				int x=node1.getX();
				int y=node1.getY();
				if(x>0){
					char a[][]=node1.getTuCopy();
					a[x][y]=a[x-1][y];
					a[x-1][y]='.';
					Node n=new Node(a,node1.getSum()+1,x-1,y);
					String s=n.getTuString();
					if(hm2.containsKey(s)){
						return n.getSum()+hm2.get(s);
					}
					if(!hm1.containsKey(s)){
						hm1.put(s, n.getSum());
						q1.add(n);
					}
				}
				if(x<2){
					char a[][]=node1.getTuCopy();
					a[x][y]=a[x+1][y];
					a[x+1][y]='.';
					Node n=new Node(a,node1.getSum()+1,x+1,y);
					String s=n.getTuString();
					if(hm2.containsKey(s)){
						return n.getSum()+hm2.get(s);
					}
					if(!hm1.containsKey(s)){
						hm1.put(s, n.getSum());
						q1.add(n);
					}
				}
				if(y>0){
					char a[][]=node1.getTuCopy();
					a[x][y]=a[x][y-1];
					a[x][y-1]='.';
					Node n=new Node(a,node1.getSum()+1,x,y-1);
					String s=n.getTuString();
					if(hm2.containsKey(s)){
						return n.getSum()+hm2.get(s);
					}
					if(!hm1.containsKey(s)){
						hm1.put(s, n.getSum());
						q1.add(n);
					}
				}
				if(y<2){
					char a[][]=node1.getTuCopy();
					a[x][y]=a[x][y+1];
					a[x][y+1]='.';
					Node n=new Node(a,node1.getSum()+1,x,y+1);
					String s=n.getTuString();
					if(hm2.containsKey(s)){
						return n.getSum()+hm2.get(s);
					}
					if(!hm1.containsKey(s)){
						hm1.put(s, n.getSum());
						q1.add(n);
					}
				}
			}
			
			
			if(!q2.isEmpty()){
				
				Node node2=q2.poll();
			//	System.out.println(node2.getTuString()+"----2");
				if(hm1.containsKey(node2.getTuString())){
					return node2.getSum()+hm1.get(node2.getTuString());
				}
				int x=node2.getX();
				int y=node2.getY();
				if(x>0){
					char a[][]=node2.getTuCopy();
					a[x][y]=a[x-1][y];
					a[x-1][y]='.';
					Node n=new Node(a,node2.getSum()+1,x-1,y);
					String s=n.getTuString();
					if(hm1.containsKey(s)){
						return n.getSum()+hm1.get(s);
					}
					if(!hm2.containsKey(s)){
						hm2.put(s, n.getSum());
						q2.add(n);
					}
				}
				if(x<2){
					char a[][]=node2.getTuCopy();
					a[x][y]=a[x+1][y];
					a[x+1][y]='.';
					Node n=new Node(a,node2.getSum()+1,x+1,y);
					String s=n.getTuString();
					if(hm1.containsKey(s)){
						return n.getSum()+hm1.get(s);
					}
					if(!hm2.containsKey(s)){
						hm2.put(s, n.getSum());
						q2.add(n);
					}
				}
				if(y>0){
					char a[][]=node2.getTuCopy();
					a[x][y]=a[x][y-1];
					a[x][y-1]='.';
					Node n=new Node(a,node2.getSum()+1,x,y-1);
					String s=n.getTuString();
					if(hm1.containsKey(s)){
						return n.getSum()+hm1.get(s);
					}
					if(!hm2.containsKey(s)){
						hm2.put(s, n.getSum());
						q2.add(n);
					}
				}
				if(y<2){
					char a[][]=node2.getTuCopy();
					a[x][y]=a[x][y+1];
					a[x][y+1]='.';
					Node n=new Node(a,node2.getSum()+1,x,y+1);
					String s=n.getTuString();
					if(hm1.containsKey(s)){
						return n.getSum()+hm1.get(s);
					}
					if(!hm2.containsKey(s)){
						hm2.put(s, n.getSum());
						q2.add(n);
					}
				}
			}
		}
		return -1;
	}
}
class Node{
	char tu[][]=new char[3][3];
	int sum=0;
	int x=0,y=0;
	public Node(char[][] tu, int sum, int x, int y) {
		super();
		this.tu = tu;
		this.sum = sum;
		this.x = x;
		this.y = y;
	}
	public char[][] getTuCopy() {
		char a[][]=new char[3][3];
		for(int i=0;i<3;i++)
			for(int j=0;j<3;j++)
				a[i][j]=tu[i][j];
		return a;
	}
	public String getTuString() {
		StringBuffer sb=new StringBuffer("");
		for(int i=0;i<3;i++)
			for(int j=0;j<3;j++)
				sb.append(tu[i][j]);
		return sb.toString();
	}
	public void setTu(char[][] tu) {
		this.tu = tu;
	}
	public int getSum() {
		return sum;
	}
	public void setSum(int sum) {
		this.sum = sum;
	}
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
}




评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值