蓝桥杯 历届试题 九宫重排(双向搜索优化)
2016-03-09 15:00
525 查看
历届试题 九宫重排
问题描述如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。
我们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
输入格式
输入第一行包含九宫的初态,第二行包含九宫的终态。
输出格式
输出最少的步数,如果不存在方案,则输出-1。
样例输入
12345678.
123.46758
样例输出
3
样例输入
13524678.
46758123.
样例输出
22
解题思路:
比较经典的搜索题,可以直接搜索或者使用双向搜索优化。AC代码:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Queue; public class Main { static Map<String,Integer> hm1 = new HashMap<String,Integer>(); static Map<String,Integer> hm2 = new HashMap<String,Integer>(); static int[] dx = {-1,0,1,0},dy = {0,-1,0,1}; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String start = br.readLine(); String end = br.readLine(); char[][] a = new char[3][3]; char[][] b = new char[3][3]; int pos = 0,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(pos); b[i][j] = end.charAt(pos); pos++; if(a[i][j] == '.'){ x1 = i; y1 = j; } if(b[i][j] == '.'){ x2 = i; y2 = j; } } } Node node1 = new Node(0,x1,y1,a); Node node2 = new Node(0,x2,y2,b); Queue<Node> qnode1 = new LinkedList<Node>(); Queue<Node> qnode2 = new LinkedList<Node>(); qnode1.add(node1); qnode2.add(node2); hm1.put(node1.getMap(), 0); hm2.put(node2.getMap(), 0); System.out.println(bfs(qnode1,qnode2)); } private static int bfs(Queue<Node> q1, Queue<Node> q2) { while(!q1.isEmpty() || !q2.isEmpty()){ if(!q1.isEmpty()){ Node node = q1.poll(); int x = node.getX(); int y = node.getY(); if(hm2.containsKey(node.getMap())){ return node.getSum() + hm2.get(node.getMap()); } for(int i = 0; i < 4; i++){ int xx = x+dx[i],yy = y+dy[i]; if(xx < 0 || xx >= 3 || yy < 0 || yy >= 3) continue; char[][] a = node.getCopy(); a[x][y] = a[xx][yy]; a[xx][yy] = '.'; Node node2 = new Node(node.sum+1,xx,yy,a); String s = node2.getMap(); if(hm2.containsKey(s)){ return node2.getSum()+hm2.get(s); } if(!hm1.containsKey(s)){ hm1.put(s, node2.getSum()); q1.add(node2); } } } if(!q2.isEmpty()){ Node node = q2.poll(); int x = node.getX(); int y = node.getY(); if(hm1.containsKey(node.getMap())){ return node.getSum() + hm1.get(node.getMap()); } for(int i = 0; i < 4; i++){ int xx = x+dx[i],yy = y+dy[i]; if(xx < 0 || xx >= 3 || yy < 0 || yy >= 3) continue; char[][] a = node.getCopy(); a[x][y] = a[xx][yy]; a[xx][yy] = '.'; Node node2 = new Node(node.sum+1,xx,yy,a); String s = node2.getMap(); if(hm1.containsKey(s)){ return node2.getSum()+hm1.get(s); } if(!hm2.containsKey(s)){ hm2.put(s, node2.getSum()); q2.add(node2); } } } } return -1; } } class Node{ int sum,x,y; char[][] a = null; public char[][] getCopy(){ char[][] copy = new char[3][3]; for(int i = 0; i < 3; i++){ for(int j = 0; j < 3; j++){ copy[i][j] = a[i][j]; } } return copy; } public String getMap(){ StringBuffer sb = new StringBuffer(); for(int i = 0; i < 3; i++){ for(int j = 0; j < 3; j++){ sb.append(a[i][j]); } } return sb.toString(); } public Node(int sum, int x, int y, char[][] a) { super(); this.sum = sum; this.x = x; this.y = y; this.a = a; } 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; } }测试数据:
Input:
12345678.
152743.86
12345678.
12356.784
2315.6784
8235164.7
12345678.
87654321.
.87654321
12345678.
Output:
6
13
17
30
28
相关文章推荐
- hdu 3095 Eleven puzzle
- poj 2785--4 Values whose Sum is 0(折半枚举)
- poj2785 折半枚举 双向查找
- 【codevs1735】【NOI01】方程的解数(双向搜索)
- 和为0的4个值
- [BZOJ 4800][Ceoi2015]Ice Hockey World Championship:双向搜索
- 杂记(消失的时光)
- linux下教你如何进行打包
- switch()语句块的出口:break;
- Spring Injection with @Resource, @Autowired and @Inject
- Servlet 基础02
- online_judge_1514
- spring中classpath和classpath*的配置区别
- HTTP Keep-Alive详解
- Android解析本地服务器的XML文件
- JAVA技术开发规范(1)——开发环境搭建
- git常用命令2
- UVA 11582
- Android闹钟 AlarmManager的使用
- linux 常用命令小汇总