第二章搜索(二)

多源BFS

例題:173. 矩陣距離
在這裏插入圖片描述
多源bfs問題
將所有源點加入到隊列,求出所有多源起點到所有點的最短距離

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {
    static int N = 1010;
    static int n;
    static int m;
    static char[][] g = new char[N][N];
    static int[][] dist = new int[N][N];
    static int[] dx = new int[]{-1, 0, 1, 0};
    static int[] dy = new int[]{0, 1, 0, -1};

    static void bfs() {
        Queue<PIIs> q = new LinkedList<PIIs>();
        for (int i = 0; i < n; i++) Arrays.fill(dist[i], -1);
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++) {
                if (g[i][j] == '1') {
                    dist[i][j] = 0;
                    q.add(new PIIs(i, j));
                }
            }
        while (!q.isEmpty()) {
            PIIs t = q.poll();
            for (int i = 0; i < 4; i++) {
                int a = t.x + dx[i];
                int b = t.y + dy[i];
                if (a < 0 || a >= n || b < 0 || b >= m) continue;
                if (dist[a][b] != -1) continue;
                dist[a][b] = dist[t.x][t.y] + 1;
                q.add(new PIIs(a, b));
            }
        }
    }

    public static void main(String[] args) throws IOException {
        Scanner scan = new Scanner(System.in);
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
        n = scan.nextInt();
        m = scan.nextInt();
        for (int i = 0; i < n; i++) {
            char[] charArray = scan.next().toCharArray();
            for (int j = 0; j < m; j++) {
                g[i][j] = charArray[j];
            }
        }
        bfs();
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                out.write(dist[i][j] + " ");
            }
            out.write("\n");
        }
        out.flush();
    }
}

class PIIs {
    public int x;
    public int y;

    public PIIs(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

最小步數模型

例題:魔板
在這裏插入圖片描述

import java.util.*;

public class Main {
    static char[][] g = new char[2][4];
    static Map<String, Integer> dist = new HashMap<>();
    static Map<String, Pair> pre = new HashMap<>();
    static Queue<String> q = new LinkedList<>();

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int x;
        String start = "", end = "";
        for (int i = 0; i < 8; i++) {
            x = sc.nextInt();
            end += (char)(x + '0');
        }
        for (int i = 0; i < 8; i++) {
            start += (char)(i + '1');
        }
        bfs(start, end);
        System.out.println(dist.get(end));
        StringBuilder res = new StringBuilder();
        while (end != start) {
            Pair p = pre.get(end);
            if (p == null) continue;
            res.append(p.c);
            end = p.s;
        }
        res.reverse();
        String realRes = res.toString();
        if (realRes.length() > 0) System.out.println(realRes);
    }

    private static void bfs(String start, String end) {
        if (start.equals(end)) return;
        q.add(start);
        dist.put(start, 0);
        while (q.size() > 0) {
            String t = q.poll();
            String[] m = new String[3];
            m[0] = move0(t);
            m[1] = move1(t);
            m[2] = move2(t);
            for (int i = 0; i < 3; i++) {
                String mm = m[i];
                if (!dist.containsKey(mm)) {
                    dist.put(mm, dist.get(t) + 1);
                    pre.put(mm, new Pair((char)(i + 'A'), t));
                    if (mm.equals(end)) break;
                    q.add(mm);
                }
            }
        }
    }

    private static String move0(String state) {
        set(state);
        for (int i = 0; i < 4; i++) {
            swap(g, 0, i, 1, i);
        }
        return get();
    }

    private static void swap(char[][] g, int x1, int y1, int x2, int y2) {
        char t = g[x1][y1];
        g[x1][y1] = g[x2][y2];
        g[x2][y2] = t;
    }

    private static String move1(String state) {
        set(state);
        char v0 = g[0][3], v1 = g[1][3];
        for (int i = 3; i > 0; i--) {
            for (int j = 0; j < 2; j++) {
                g[j][i] = g[j][i - 1];
            }
        }
        g[0][0] = v0;
        g[1][0] = v1;
        return get();
    }

    private static String move2(String state) {
        set(state);
        char v = g[0][1];
        g[0][1] = g[1][1];
        g[1][1] = g[1][2];
        g[1][2] = g[0][2];
        g[0][2] = v;
        return get();
    }

    private static void set(String state) {
        for (int i = 0; i < 4; i++) {
            g[0][i] = state.charAt(i);
        }
        for (int i = 3, j = 4; i >= 0; i--, j++) {
            g[1][i] = state.charAt(j);
        }
    }

    private static String get() {
        StringBuilder res = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            res.append(g[0][i]);
        }
        for (int i = 3; i >= 0; i--) {
            res.append(g[1][i]);
        }
        return res.toString();
    }
}
class Pair{
    char c;
    String s;

    public Pair(char c, String s) {
        this.c = c;
        this.s = s;
    }
}

雙端隊列廣搜

例題:175. 電路維修
在這裏插入圖片描述
【WA了】

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Scanner;

public class Main {
    static int N = 510;
    static int n;
    static int m;
    static char[][] g = new char[N][N];
    static int[][] dist = new int[N][N];
    static boolean[][] st = new boolean[N][N];

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt();
        while (T-- > 0) {
            n = sc.nextInt();
            m = sc.nextInt();
            for (int i = 0; i < n; i++) {
                g[i] = sc.next().toCharArray();
            }
            if ((n + m & 1) == 1) {
                System.out.println("NO SOLUTION");
            }else {
                System.out.println(bfs());
            }
        }
    }

    private static int bfs() {
        LinkedList<Pair> q = new LinkedList<>();
        for (boolean[] x : st) Arrays.fill(x, false);
        for (int[] x : dist) Arrays.fill(x, 0x3f);
        char[] cs = "\\/\\/".toCharArray();//感覺問題出在這
        int[] dx = {-1, -1, 1, 1};
        int[] dy = {-1, 1, 1, -1};
        int[] ix = {-1, -1, 0, 0};
        int[] iy = {-1, 0, 0, -1};
        dist[0][0] = 0;
        q.add(new Pair(0, 0));
        while (!q.isEmpty()) {
            Pair t = q.poll();
            int x = t.x, y = t.y;
            if (x == n && y == m) return dist[x][y];
            if (st[x][y]) continue;
            st[x][y] = true;
            for (int i = 0; i < 4; i++) {
                int a = x + dx[i];
                int b = y + dy[i];
                if (a < 0 || a > n || b < 0 || b > m) continue;
                int ga = x + ix[i];
                int gb = y + iy[i];
                int w = g[ga][gb] != cs[i] ? 1 : 0;
                int d = dist[x][y] + w;
                if (d <= dist[a][b]) {
                    dist[a][b] = d;
                    if (w == 0) {
                        q.addFirst(new Pair(a, b));//Queue沒有這個函數
                    }else {
                        q.add(new Pair(a, b));
                    }
                }
            }
        }
        return -1;//一定不會被執行到
    }
}
class Pair{
    int x;
    int y;

    public Pair(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章