蓝桥杯 历届试题 九宫重排 BFS Java

来源:互联网 发布:赣州教育软件代理 编辑:程序博客网 时间:2024/05/01 11:41

    标准的BFS题,将九宫格哈希以后记录搜索的状态,用Set边搜索边去重,写的代码用了点面向对象的东西


    AC代码:

import java.util.*;public class Main {//f为初始状态,e为最终状态static int f[][] = new int[3][3], e[][] = new int[3][3];//将'.'表示成9这个数字static int p = 9;static int dir[][] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};public static void main(String[] args) throws CloneNotSupportedException {String fs, es;Scanner in = new Scanner(System.in);int ans;fs = in.nextLine();es = in.nextLine();//将String映射到九宫格for (int i = 0; i < fs.length(); i++) {f[i / 3][i - i / 3 * 3] = (fs.charAt(i) == '.' ? p : fs.charAt(i) - '0');e[i / 3][i - i / 3 * 3] = (es.charAt(i) == '.' ? p : es.charAt(i) - '0');}ans = bfs();System.out.println(ans);in.close();}static boolean check(int x, int y) {if (x < 0 || x >= 3 || y < 0 || y >= 3)return false;return true;}static int bfs() throws CloneNotSupportedException {Queue<qnode> Q = new LinkedList<>();//Set用于防止重复搜索以前的状态Set<hnode> S = new HashSet<>();qnode bqn;hnode bhn, ehn;bqn = new qnode(f, 0);bhn = new hnode(f);ehn = new hnode(e);Q.offer(bqn);S.add(bhn);while(!Q.isEmpty()) {qnode tn = Q.element();Q.remove();int[][] a = new int[3][];for (int i = 0; i < 3; i++) {a[i] = tn.a[i].clone();}int cnt = tn.cnt;int x = 0, y = 0;boolean flag = false; //cut timefor (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {if (a[i][j] == p) {x = i; y = j;flag = true;break;}}if (flag) break;}for (int i = 0; i < 4; i++) {int nx, ny, t;nx = x + dir[i][0];ny = y + dir[i][1];if (check(nx, ny)) {t = a[nx][ny];a[nx][ny] = a[x][y];a[x][y] = t;hnode thn = new hnode(a);if (thn.equals(ehn)) {return cnt + 1;  //BFS找到就是最小次数,直接返回}if (!S.contains(thn)) {S.add(thn);qnode tt = new qnode(a, cnt + 1);Q.add(tt);}t = a[nx][ny];  //debug 换方向要把九宫格先还原a[nx][ny] = a[x][y];a[x][y] = t;}}}return -1;}}//放在Set中的元素class hnode {//hash用于HashSet,也用于判等//把hash值算好存起来,回来直接return,节省时间int hash;public hnode() {}public hnode(int[][] a) {int hc = 0;for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {hc *= 10;hc += a[i][j];}}this.hash = hc;}@Overridepublic boolean equals(Object object) {hnode thn = (hnode)object;return thn.hash == hash;}@Overridepublic int hashCode() {return hash;}}//队列中的元素class qnode extends hnode {int[][] a; //记录九宫格状态int cnt;  //记录步数public qnode() {}public qnode(int[][] a, int cnt) {this.a = new int[3][];for (int i = 0; i < 3; i++) {this.a[i] = a[i].clone();}this.cnt = cnt;}@Overrideprotected Object clone() throws CloneNotSupportedException {return new qnode(a, cnt);}}


之前试了试String,不知道是不是因为遍历和ts = ts + others太慢,超时,如果有大神比较清楚瓶颈在哪给说一声,不胜感激!

超时代码:

import java.util.*;public class Main {static int p = 9;static int dir[][] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};static String fs, es;public static void main(String[] args) {Scanner in = new Scanner(System.in);int ans;fs = in.nextLine();es = in.nextLine();ans = bfs();System.out.println(ans);in.close();}static boolean check(int x, int y) {if (x < 0 || x >= 3 || y < 0 || y >= 3)return false;return true;}static int bfs() {Queue<qnode> Q = new LinkedList<qnode>();Set<Integer> S = new HashSet<Integer>();qnode bqn;bqn = new qnode(fs, 0);Q.offer(bqn);S.add(fs.hashCode());while(!Q.isEmpty()) {qnode tn = Q.element();Q.remove();String m = tn.m;int cnt = tn.cnt;int x = 0, y = 0, len = m.length();int[][] a = new int[3][3];for (int i = 0; i < len; i++) {a[i / 3][i - i / 3 * 3] = (m.charAt(i) == '.' ? p : m.charAt(i) - '0');if (m.charAt(i) == '.') {x = i / 3;y = i - i / 3 * 3;}}for (int i = 0; i < 4; i++) {int nx, ny, t;nx = x + dir[i][0];ny = y + dir[i][1];if (check(nx, ny)) {t = a[nx][ny];a[nx][ny] = a[x][y];a[x][y] = t;String ts = "";for (int w = 0; w < 3; w++) {for (int j = 0; j < 3; j++) {ts = ts + (a[w][j] == p ? "." : a[w][j]); //debug}}if (ts.equals(es)) {return cnt + 1;}int tshc = ts.hashCode();if (!S.contains(tshc)) {S.add(tshc);qnode tt = new qnode(ts, cnt + 1);Q.add(tt);}t = a[nx][ny];  //debuga[nx][ny] = a[x][y];a[x][y] = t;}}}return -1;}}class qnode {String m;int cnt;public qnode() {}public qnode(String m, int cnt) {this.m = m;this.cnt = cnt;}}


0 0
原创粉丝点击