博客
关于我
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/

    你可能感兴趣的文章
    POI导出Excel2003
    查看>>
    POI数据获取及坐标纠偏
    查看>>
    Quartz入门看这一篇文章就够了
    查看>>
    POI解析Excel【poi的坑——空行处理】
    查看>>
    POI:POI+JXL实现xls文件添加水印
    查看>>
    POI:POI实现docx文件添加水印
    查看>>
    POJ 1006
    查看>>
    Quartz中时间表达式的设置-----corn表达式
    查看>>
    poj 1035
    查看>>
    POJ 1061 青蛙的约会 (扩展欧几里得)
    查看>>
    Quartz2.2.1简单使用
    查看>>
    POJ 1080 Human Gene Functions(DP:LCS)
    查看>>
    Quant 开源项目教程
    查看>>
    POJ 1088 滑雪
    查看>>
    POJ 1095 Trees Made to Order
    查看>>
    POJ 1113 Wall(计算几何--凸包的周长)
    查看>>
    poj 1125Stockbroker Grapevine(最短路)
    查看>>
    Qualitor processVariavel.php 未授权命令注入漏洞复现(CVE-2023-47253)
    查看>>
    poj 1151 (未完成) 扫描线 线段树 离散化
    查看>>
    POJ 1151 / HDU 1542 Atlantis 线段树求矩形面积并
    查看>>