博客
关于我
AcWing 845. 八数码(BFS)
阅读量:346 次
发布时间:2019-03-04

本文共 3143 字,大约阅读时间需要 10 分钟。

为了解决这个问题,我们需要找到将给定网格中的“x”移动到指定位置所需的最少交换次数。我们可以使用广度优先搜索(BFS)来探索所有可能的交换状态,从而找到最短路径。

方法思路

  • 问题分析:我们需要将“x”移动到网格中的指定位置,同时将其他数字排列成正确的顺序。每次交换只能移动“x”上下左右相邻的位置。
  • 状态表示:将网格状态表示为一个字符串,每个字符对应网格中的一个位置。例如,网格中的每个位置按行优先排列。
  • BFS算法:使用队列来进行BFS,记录每个状态的访问次数和父节点。每次从队列中取出当前状态,生成所有可能的下一个状态,直到找到目标状态或队列为空。
  • 状态转换:对于每个状态,找到“x”的位置,尝试移动到四个方向,生成新的状态字符串,并检查是否已经访问过。
  • 解决代码

    import java.io.BufferedReader;import java.io.IOException;import java.util.ArrayDeque;import java.util.Deque;import java.util.HashMap;import java.util.Map;class Main {    static final String START = "12345678x";    static final String[] DIRECTIONS = { "-1,0,0,-1", "1,0,0,1", "0,-1,-1,0", "0,1,1,1" };    static final int[][] D = new int[][] { {-1, 0, 0, 0}, {1, 0, 0, 0}, {0, 0, -1, 1}, {0, 0, 1, -1} };    static final String[] dx = { "-1", "1", "0", "0" };    static final String[] dy = { "0", "0", "-1", "1" };    static Map
    d = new HashMap<>(); static Map
    strsh = new HashMap<>(); static Map
    pre = new HashMap<>(); static Deque
    q = new ArrayDeque<>(); static int idx = 0; static int res = -1; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String input = br.readLine(); input = input.replace(" ", ""); System.out.println(bfs(input)); } private static int bfs(String start) { q.clear(); d.clear(); strsh.clear(); pre.clear(); if (start.equals(START)) return 0; q.add(start); d.put(start, 0); strsh.put(start, idx); pre.put(start, null); idx++; String target = START; while (!q.isEmpty()) { String current = q.poll(); if (current.equals(target)) { for (int i = res; i != -1; i = pre.get(i)) { res = pre.get(i); if (res == null) break; } return d.get(current); } int x = current.indexOf('x'); if (x == -1) continue; int x_row = x / 3; int x_col = x % 3; for (int i = 0; i < 4; i++) { int new_row = x_row + D[i][0]; int new_col = x_col + D[i][1]; if (new_row < 0 || new_row >= 3 || new_col < 0 || new_col >= 3) continue; String[] chars = current.toCharArray(); chars[x], chars[new_row * 3 + new_col] = chars[new_row * 3 + new_col], chars[x]; String next = new String(chars); if (!d.containsKey(next)) { d.put(next, d.get(current) + 1); strsh.put(next, idx); pre.put(next, current); idx++; q.add(next); if (next.equals(target)) { res = idx; } } } } return -1; }}

    代码解释

  • 输入处理:读取输入字符串并去除空格。
  • BFS初始化:将初始状态加入队列,记录访问状态和距离。
  • 状态处理:对于每个状态,找到“x”的位置,尝试移动到四个方向,生成新的状态字符串。
  • 状态转换:检查新状态是否已访问,如果不,记录父节点和距离,加入队列。
  • 目标检查:如果找到目标状态,返回当前距离。
  • 通过这种方法,我们可以有效地探索所有可能的交换状态,找到最少交换次数。

    转载地址:http://iure.baihongyu.com/

    你可能感兴趣的文章
    POJ1240 m叉树
    查看>>
    Poj1328--Radar Installation(区间选点)
    查看>>
    POJ1384Piggy-Bank(DP)
    查看>>
    POJ1417 True Liars —— 并查集 + DP
    查看>>
    Poj1459 Power Network 预流推进
    查看>>
    POJ1502(MPI Maelstrom)
    查看>>
    poj1568 Find the Winning Move[极大极小搜索+alpha-beta剪枝]
    查看>>
    poj1730 - Perfect Pth Powers(完全平方数)(水题)
    查看>>
    poj1753——Flip Game
    查看>>
    poj1936 假期计划第一水
    查看>>
    poj1958-汉诺四塔问题(三种方法)
    查看>>
    poj1988(并查集)
    查看>>
    POJ2007+几何+极角排序
    查看>>
    poj2039
    查看>>
    poj2135(简单的最小费用流问题)
    查看>>
    POJ2251
    查看>>
    POJ2253-Frogger
    查看>>
    POJ2728 Desert King
    查看>>
    poj3074 DLX精确覆盖
    查看>>
    Qt笔记——QLable+QPixmap图片缩放踩坑
    查看>>