九宫重排_康拓展开_bfs
生活随笔
收集整理的這篇文章主要介紹了
九宫重排_康拓展开_bfs
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
歷屆試題 九宮重排 ? 時間限制:1.0s ? 內存限制:256.0MB 問題描述 如下面第一個圖的九宮格中,放著 1~8 的數字卡片,還有一個格子空著。與空格子相鄰的格子中的卡片可以移動到空格中。經過若干次移動,可以形成第二個圖所示的局面。
我們把第一個圖的局面記為:12345678.
把第二個圖的局面記為:123.46758
顯然是按從上到下,從左到右的順序記錄數字,空格記為句點。
本題目的任務是已知九宮的初態和終態,求最少經過多少步的移動可以到達。如果無論多少步都無法到達,則輸出-1。 輸入格式 輸入第一行包含九宮的初態,第二行包含九宮的終態。 輸出格式 輸出最少的步數,如果不存在方案,則輸出-1。 樣例輸入 12345678.
123.46758 樣例輸出 3 樣例輸入 13524678.
46758123. 樣例輸出 22 拿到這個題的時候沒什么思路,之前也做過bfs的題,最大的問題在于狀態的保存,后來看到有個編碼題用到了康拓展開,豁然開朗,數學真的是奇妙啊!還有很多不知道的東西呢! 又知道了java的幾個坑,哪怕是數組直接賦值也是賦的地址,添加到鏈表之類的也是地址,想要不受干擾只能手工拷貝。 1 package study_code; 2 3 import java.util.LinkedList; 4 import java.util.Queue; 5 import java.util.Scanner; 6 7 public class 八數碼 { 8 9 static int[] vis = new int [900900]; //判斷哈希值是否被訪問 10 static int[] f = new int[9]; //保存階乘 11 static int end; //最終狀態的哈希值 12 static node start = new node(); 13 static String resPath; 14 static int[][] dir = {{-1,0},{1,0},{0,-1},{0,1}}; 15 static char[] dirc = {'U','D','L','R'}; 16 static class node{ 17 int loc; //記錄當前空格位置 用一個數字記錄 1-9 18 int s[]; //記錄當前所有數字的位置 19 int hashVal; //當前狀態的哈希值 20 String path = ""; //記錄當前路徑 21 public node() { 22 } 23 } 24 25 public static void fac() { 26 f[0] = 1; 27 for (int i = 1; i < f.length; i++) { 28 f[i] = f[i-1] * i; 29 } 30 } 31 32 //康拓展開 33 public static int getHash(int[] s) { 34 int res = 0; 35 for (int i = 0; i < s.length; i++) { 36 int index =0; 37 for (int j = i+1; j < s.length; j++) { 38 if (s[j]<s[i]) { 39 index++; 40 } 41 } 42 res += index*f[9-1-i]; 43 } 44 return res; 45 } 46 47 48 public static boolean bfs() { 49 Queue<node> q = new LinkedList<node>(); 50 q.offer(start); 51 vis[start.hashVal] = 1; 52 while (!q.isEmpty()) { 53 node cur = q.poll(); 54 vis[cur.hashVal] = 1; 55 if (cur.hashVal == end) { 56 resPath = cur.path; 57 return true; 58 } 59 int x =cur.loc/3; 60 int y =cur.loc%3; 61 for (int i = 0; i < 4; i++) { 62 int tx = x + dir[i][0]; 63 int ty = y + dir[i][1]; 64 if (tx<0||ty<0||tx>=3||ty>=3) { 65 continue; 66 } 67 node temp = new node(); 68 temp.loc = tx*3+ty; 69 temp.path = cur.path+dirc[i]; 70 temp.s = cur.s.clone(); 71 //交換空格的位置 72 temp.s[cur.loc] = temp.s[temp.loc]; 73 temp.s[temp.loc] = 0; 74 75 temp.hashVal = getHash(temp.s); 76 if (vis[temp.hashVal] == 1) { 77 continue; 78 } 79 q.offer(temp); 80 vis[temp.hashVal] = 1; 81 } 82 } 83 return false; 84 85 86 87 } 88 public static void main(String[] args) { 89 Scanner sc = new Scanner(System.in); 90 fac(); 91 String t = sc.nextLine(); 92 char[] c = t.toCharArray(); 93 int[] n = new int[c.length]; 94 for (int i = 0; i < c.length; i++) { 95 if (c[i] == '.') { 96 n[i] = 0; 97 start.loc = i; 98 }else { 99 n[i] = c[i] - '0'; 100 } 101 } 102 start.s = n.clone(); 103 start.hashVal = getHash(start.s); 104 t = sc.nextLine(); 105 c = t.toCharArray(); 106 n = new int[c.length]; 107 for (int i = 0; i < c.length; i++) { 108 if (c[i] == '.') { 109 n[i] = 0; 110 }else { 111 n[i] = c[i] - '0'; 112 } 113 } 114 end = getHash(n); 115 bfs(); 116 System.out.println(resPath.length()); 117 } 118 }
?
我們把第一個圖的局面記為:12345678.
把第二個圖的局面記為:123.46758
顯然是按從上到下,從左到右的順序記錄數字,空格記為句點。
本題目的任務是已知九宮的初態和終態,求最少經過多少步的移動可以到達。如果無論多少步都無法到達,則輸出-1。 輸入格式 輸入第一行包含九宮的初態,第二行包含九宮的終態。 輸出格式 輸出最少的步數,如果不存在方案,則輸出-1。 樣例輸入 12345678.
123.46758 樣例輸出 3 樣例輸入 13524678.
46758123. 樣例輸出 22 拿到這個題的時候沒什么思路,之前也做過bfs的題,最大的問題在于狀態的保存,后來看到有個編碼題用到了康拓展開,豁然開朗,數學真的是奇妙啊!還有很多不知道的東西呢! 又知道了java的幾個坑,哪怕是數組直接賦值也是賦的地址,添加到鏈表之類的也是地址,想要不受干擾只能手工拷貝。 1 package study_code; 2 3 import java.util.LinkedList; 4 import java.util.Queue; 5 import java.util.Scanner; 6 7 public class 八數碼 { 8 9 static int[] vis = new int [900900]; //判斷哈希值是否被訪問 10 static int[] f = new int[9]; //保存階乘 11 static int end; //最終狀態的哈希值 12 static node start = new node(); 13 static String resPath; 14 static int[][] dir = {{-1,0},{1,0},{0,-1},{0,1}}; 15 static char[] dirc = {'U','D','L','R'}; 16 static class node{ 17 int loc; //記錄當前空格位置 用一個數字記錄 1-9 18 int s[]; //記錄當前所有數字的位置 19 int hashVal; //當前狀態的哈希值 20 String path = ""; //記錄當前路徑 21 public node() { 22 } 23 } 24 25 public static void fac() { 26 f[0] = 1; 27 for (int i = 1; i < f.length; i++) { 28 f[i] = f[i-1] * i; 29 } 30 } 31 32 //康拓展開 33 public static int getHash(int[] s) { 34 int res = 0; 35 for (int i = 0; i < s.length; i++) { 36 int index =0; 37 for (int j = i+1; j < s.length; j++) { 38 if (s[j]<s[i]) { 39 index++; 40 } 41 } 42 res += index*f[9-1-i]; 43 } 44 return res; 45 } 46 47 48 public static boolean bfs() { 49 Queue<node> q = new LinkedList<node>(); 50 q.offer(start); 51 vis[start.hashVal] = 1; 52 while (!q.isEmpty()) { 53 node cur = q.poll(); 54 vis[cur.hashVal] = 1; 55 if (cur.hashVal == end) { 56 resPath = cur.path; 57 return true; 58 } 59 int x =cur.loc/3; 60 int y =cur.loc%3; 61 for (int i = 0; i < 4; i++) { 62 int tx = x + dir[i][0]; 63 int ty = y + dir[i][1]; 64 if (tx<0||ty<0||tx>=3||ty>=3) { 65 continue; 66 } 67 node temp = new node(); 68 temp.loc = tx*3+ty; 69 temp.path = cur.path+dirc[i]; 70 temp.s = cur.s.clone(); 71 //交換空格的位置 72 temp.s[cur.loc] = temp.s[temp.loc]; 73 temp.s[temp.loc] = 0; 74 75 temp.hashVal = getHash(temp.s); 76 if (vis[temp.hashVal] == 1) { 77 continue; 78 } 79 q.offer(temp); 80 vis[temp.hashVal] = 1; 81 } 82 } 83 return false; 84 85 86 87 } 88 public static void main(String[] args) { 89 Scanner sc = new Scanner(System.in); 90 fac(); 91 String t = sc.nextLine(); 92 char[] c = t.toCharArray(); 93 int[] n = new int[c.length]; 94 for (int i = 0; i < c.length; i++) { 95 if (c[i] == '.') { 96 n[i] = 0; 97 start.loc = i; 98 }else { 99 n[i] = c[i] - '0'; 100 } 101 } 102 start.s = n.clone(); 103 start.hashVal = getHash(start.s); 104 t = sc.nextLine(); 105 c = t.toCharArray(); 106 n = new int[c.length]; 107 for (int i = 0; i < c.length; i++) { 108 if (c[i] == '.') { 109 n[i] = 0; 110 }else { 111 n[i] = c[i] - '0'; 112 } 113 } 114 end = getHash(n); 115 bfs(); 116 System.out.println(resPath.length()); 117 } 118 }
?
轉載于:https://www.cnblogs.com/16crow/p/6641639.html
總結
以上是生活随笔為你收集整理的九宫重排_康拓展开_bfs的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 几种进程间的通信方式
- 下一篇: 利用jquery的qrcode.js插件