如图1的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成图2所示的局面。
我们把图1的局面记为:12345678.
把图2的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
例如:
输入数据为:
12345678.
123.46758
则,程序应该输出:
3
再如:
输入:
13524678.
46758123.
则,程序输出:
22
资源约定:
峰值内存消耗(含虚拟机) < 64M
CPU消耗 < 2000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
bfs,队列里记录变换后的字符串,'.'在字符串中的位置,已经变换步数,同时每有一个字符串加入队列,就用map进行标记,以后不再加入队列。
代码:
import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Queue; import java.util.Scanner; class Th<T,U,V>{ T first; U second; V third; public Th() {first = null;second = null;third = null;} public Th(T f,U s,V t) { first = f; second = s; third = t; } } public class Main { private static Scanner sc = new Scanner(System.in); private static String s = "",t = ""; private static int [][] dir = {{1,3,0,0},{1,3,-1,0},{-1,3,0,0},{1,3,-3,0}, {1,3,-3,-1},{-1,3,-3,0},{1,-3,0,0},{1,-3,-1,0},{-1,-3,0,0}}; private static boolean flag = false; public static void main(String[] args) { int ans = -1; String s = sc.next(); String t = sc.next(); Queue<Th<String,Integer,Integer>> q = new LinkedList(); Map<String,Boolean> map = new HashMap(); for(int i = 0;i < s.length();i ++) { if(s.charAt(i) == '.') { q.offer(new Th(s,i,0)); break; } } map.put(s, true); while(!q.isEmpty()) { String temp = q.element().first; int n = q.element().second; int d = q.element().third; q.poll(); for(int i = 0;i < 4;i ++) { if(dir[n][i] == 0 || n + dir[n][i] < 0 || n + dir[n][i] >= 9) continue; StringBuilder ss = new StringBuilder(temp); ss.setCharAt(n, ss.charAt(n + dir[n][i])); ss.setCharAt(n + dir[n][i], '.'); if(!map.containsKey(ss.toString())) { if(ss.toString().equals(t)) { ans = d + 1; flag = true; break; } q.offer(new Th(ss.toString(),n + dir[n][i],d + 1)); map.put(ss.toString(), true); } } if(flag) break; } System.out.println(ans); } }